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 | |
27 | class KAction; |
28 | class QAction; |
29 | class KToggleAction; |
30 | class KActionCollection; |
31 | |
32 | class KoCompositeOp; |
33 | class KoColorSpace; |
34 | class KUndo2MagicString; |
35 | |
36 | class KisDoc2; |
37 | class KisFilterStrategy; |
38 | class KisView2; |
39 | class KisFilterConfiguration; |
40 | class KisActionManager; |
41 | |
42 | /** |
43 | * The node manager passes requests for new layers or masks on to the mask and layer |
44 | * managers. |
45 | */ |
46 | class KRITAUI_EXPORT KisNodeManager : public QObject |
47 | { |
48 | |
49 | Q_OBJECT |
50 | |
51 | public: |
52 | |
53 | KisNodeManager(KisView2 * view, KisDoc2 * doc); |
54 | ~KisNodeManager(); |
55 | |
56 | |
57 | signals: |
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 | |
70 | public: |
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 | |
108 | public 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 | |
203 | public: |
204 | |
205 | |
206 | void shear(double angleX, double angleY); |
207 | |
208 | void scale(double sx, double sy, KisFilterStrategy *filterStrategy); |
209 | |
210 | private: |
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 | |