1/*
2 * Copyright (C) 2007 Boudewijn Rempt <boud@valdyas.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18#ifndef KIS_NODE_MANAGER
19#define KIS_NODE_MANAGER
20
21#include <QObject>
22#include <QList>
23
24#include "kis_types.h"
25#include <krita_export.h>
26
27class KAction;
28class QAction;
29class KToggleAction;
30class KActionCollection;
31
32class KoCompositeOp;
33class KoColorSpace;
34class KUndo2MagicString;
35
36class KisDoc2;
37class KisFilterStrategy;
38class KisView2;
39class KisFilterConfiguration;
40class KisActionManager;
41
42/**
43 * The node manager passes requests for new layers or masks on to the mask and layer
44 * managers.
45 */
46class KRITAUI_EXPORT KisNodeManager : public QObject
47{
48
49 Q_OBJECT
50
51public:
52
53 KisNodeManager(KisView2 * view, KisDoc2 * doc);
54 ~KisNodeManager();
55
56
57signals:
58
59 /// emitted whenever a node is selected.
60 void sigNodeActivated(KisNodeSP node);
61
62 /// emitted whenever a different layer is selected.
63 void sigLayerActivated(KisLayerSP layer);
64
65 /// for the layer box: this sets the current node in the layerbox
66 /// without telling the node manager that the node is activated,
67 /// preventing loops (I think...)
68 void sigUiNeedChangeActiveNode(KisNodeSP node);
69
70public:
71
72 void setup(KActionCollection * collection, KisActionManager* actionManager);
73 void updateGUI();
74
75 /// Convenience function to get the active layer or mask
76 KisNodeSP activeNode();
77
78 /// convenience function to get the active layer. If a mask is
79 /// active, it's parent layer is the active layer.
80 KisLayerSP activeLayer();
81
82 /// Get the paint device the user wants to paint on now
83 KisPaintDeviceSP activePaintDevice();
84
85 /**
86 * @return the active color space used for composition, meaning the color space
87 * of the active mask, or the color space of the parent of the active layer
88 */
89 const KoColorSpace* activeColorSpace();
90
91 /**
92 * Sets opacity for the node in a universal way (masks/layers)
93 */
94 void setNodeOpacity(KisNodeSP node, qint32 opacity, bool finalChange);
95
96 /**
97 * Sets compositeOp for the node in a universal way (masks/layers)
98 */
99 void setNodeCompositeOp(KisNodeSP node, const KoCompositeOp* compositeOp);
100
101 /**
102 * @brief setSelectedNodes set the list of nodes selected in the layerbox. Selected nodes are not necessarily active nodes.
103 * @param nodes the selected nodes
104 */
105 void setSelectedNodes(QList<KisNodeSP> nodes);
106 QList<KisNodeSP> selectedNodes();
107
108public slots:
109
110 /**
111 * Explicitly activates \p node
112 * The UI will be noticed that active node has been changed.
113 * Both sigNodeActivated and sigUiNeedChangeActiveNode are emitted.
114 *
115 * WARNING: normally you needn't call this method manually. It is
116 * automatically called when a node is added to the graph. If you
117 * have some special cases when you need to activate a node, consider
118 * adding them to KisDummiesFacadeBase instead. Calling this method
119 * directly should be the last resort.
120 *
121 * \see slotUiActivatedNode for comparison
122 */
123 void slotNonUiActivatedNode(KisNodeSP node);
124
125 /**
126 * Activates \p node.
127 * All non-ui listeners are notified with sigNodeActivated,
128 * sigUiNeedChangeActiveNode is *not* emitted.
129 *
130 * \see activateNode
131 */
132 void slotUiActivatedNode(KisNodeSP node);
133
134 /**
135 * Adds a node without searching appropriate position for it.
136 * You *must* ensure that the node is allowed to be added to
137 * the parent, otherwise you'll get an assert.
138 */
139 void addNodeDirect(KisNodeSP node, KisNodeSP parent, KisNodeSP aboveThis);
140
141 /**
142 * Moves a node without searching appropriate position for it.
143 * You *must* ensure that the node is allowed to be added to
144 * the parent, otherwise you'll get an assert.
145 */
146 void moveNodeDirect(KisNodeSP node, KisNodeSP parent, KisNodeSP aboveThis);
147
148
149 void toggleIsolateActiveNode();
150 void toggleIsolateMode(bool checked);
151 void slotUpdateIsolateModeAction();
152 void slotTryFinishIsolatedMode();
153
154 void moveNodeAt(KisNodeSP node, KisNodeSP parent, int index);
155 void createNode(const QString& nodeType, bool quiet = false);
156 void convertNode(const QString &nodeType);
157 void nodesUpdated();
158 void nodeProperties(KisNodeSP node);
159 void nodeOpacityChanged(qreal opacity, bool finalChange);
160 void nodeCompositeOpChanged(const KoCompositeOp* op);
161 void duplicateActiveNode();
162 void removeNode();
163 void mirrorNodeX();
164 void mirrorNodeY();
165 void mirrorNode(KisNodeSP node, const KUndo2MagicString& commandName, Qt::Orientation orientation);
166 void activateNextNode();
167 void activatePreviousNode();
168
169 /**
170 * move the active node up the nodestack.
171 */
172 void raiseNode();
173
174 /**
175 * move the active node down the nodestack
176 */
177 void lowerNode();
178
179 /**
180 * move the activenode to the top-most position of the nodestack
181 * If the node is a mask, the stack is limited to the set of masks
182 * belonging to the current layer.
183 */
184 void nodeToTop();
185
186 /**
187 * move the activenode to the bottom-most position of the nodestack
188 * If the node is a mask, the stack is limited to the set of masks
189 * belonging to the current layer.
190 */
191 void nodeToBottom();
192
193 void rotate(double radians);
194 void rotate180();
195 void rotateLeft90();
196 void rotateRight90();
197
198 void saveNodeAsImage();
199
200 // merges the active layer with the layer below it.
201 void mergeLayerDown();
202
203public:
204
205
206 void shear(double angleX, double angleY);
207
208 void scale(double sx, double sy, KisFilterStrategy *filterStrategy);
209
210private:
211 /**
212 * Scales opacity from the range 0...1
213 * to the integer range 0...255
214 */
215 qint32 convertOpacityToInt(qreal opacity);
216 void removeSelectedNodes(QList<KisNodeSP> selectedNodes, bool removeActive = true);
217 void removeSingleNode(KisNodeSP node);
218
219 struct Private;
220 Private * const m_d;
221};
222
223#endif
224