chalk

kis_tool_manager.cpp
1/*
2 * Copyright (c) 2005 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#include "kopalettemanager.h"
19
20#include "kis_part_layer.h"
21#include "kis_tool_manager.h"
22#include "kis_tool_registry.h"
23#include "kis_tool_dummy.h"
24#include "kis_canvas_subject.h"
25#include "kis_tool_controller.h"
26#include "kis_view.h"
27#include "kis_canvas.h"
28#include "kis_cursor.h"
29#include "KoToolBox.h"
30#include "kis_image.h"
31#include "kis_layer.h"
32#include "kis_input_device.h"
33
34
35KisToolManager::KisToolManager(KisCanvasSubject * parent, KisCanvasController * controller)
36 : m_subject(parent),
37 m_controller(controller)
38{
39 m_toolBox = 0;
40 m_oldTool = 0;
41 m_dummyTool = 0;
42 m_paletteManager = 0;
43 m_actionCollection = 0;
44 m_tools_disabled = false;
45 setup = false;
46}
47
48KisToolManager::~KisToolManager()
49{
50 delete m_dummyTool;
51}
52
53void KisToolManager::setUp(KoToolBox * toolbox, KoPaletteManager * paletteManager, TDEActionCollection * actionCollection)
54{
55 if (setup) {
56 resetToolBox( toolbox );
57 return;
58 }
59
60 m_toolBox = toolbox;
61 m_paletteManager = paletteManager;
62 m_actionCollection = actionCollection;
63
64 // Dummy tool for when the layer is locked or invisible
65 if (!m_dummyTool)
66 m_dummyTool = KisToolDummyFactory().createTool(actionCollection);
67
68 TQValueVector<KisInputDevice> inputDevices = KisInputDevice::inputDevices();
69
70 for (TQ_UINT32 inputDevice = 0; inputDevice < inputDevices.count(); inputDevice++) {
71 m_inputDeviceToolSetMap[inputDevices[inputDevice]] = KisToolRegistry::instance()->createTools(actionCollection, m_subject);
72 }
73
74 m_tools = m_inputDeviceToolSetMap[KisInputDevice::mouse()];
75 for (vKisTool_it it = m_tools.begin(); it != m_tools.end(); ++it) {
76 KisTool * t = *it;
77 if (!t) continue;
78 toolbox->registerTool( t->action(), t->toolType(), t->priority() );
79 }
80
81 toolbox->setupTools();
82
83 KisTool * t = findTool("tool_brush");
84 if (t) {
85 t->activate();
86 setCurrentTool(t);
87 }
88 setup = true;
89
90}
91
92
93
94void KisToolManager::youAintGotNoToolBox()
95{
96 m_toolBox = 0;
97 m_oldTool = currentTool();
98}
99
100void KisToolManager::resetToolBox(KoToolBox * toolbox)
101{
102 m_toolBox = toolbox;
103
104 m_tools = m_inputDeviceToolSetMap[KisInputDevice::mouse()];
105 for (vKisTool_it it = m_tools.begin(); it != m_tools.end(); ++it) {
106 KisTool * t = *it;
107 if (!t) continue;
108 m_toolBox->registerTool( t->action(), t->toolType(), t->priority() );
109 }
110
111 toolbox->setupTools();
112
113#if 0 // Because I cannot find out how to reset the toolbox so the button is depressed, we reset the tool to brush
114 setCurrentTool(findTool("tool_brush"));
115#else
116 if (m_oldTool) {
117 // restore the old current tool
118 setCurrentTool(m_oldTool);
119 m_oldTool = 0;
120 }
121#endif
122
123}
124
125void KisToolManager::updateGUI()
126{
127 Q_ASSERT(m_subject);
128 if (m_subject == 0) {
129 // "Eek, no parent!
130 return;
131 }
132
133 if (!m_toolBox) return;
134
135 KisImageSP img = m_subject->currentImg();
136 KisLayerSP l = 0;
137
138 bool enable = false;
139
140
141 KisPartLayer * partLayer = dynamic_cast<KisPartLayer*>(l.data());
142
143 if (img) {
144 l = img->activeLayer();
145 enable = l && !l->locked() && l->visible() && (partLayer == 0);
146 }
147
148 m_toolBox->enableTools( enable );
149
150 KisTool * current = currentTool();
151
152 // XXX: Fix this properly: changing the visibility of a layer causes this cause to be executed twice!
153 if (!enable && current != m_dummyTool) {
154 // Store the current tool
155 m_oldTool = currentTool();
156 // Set the dummy tool
157 if (!m_dummyTool) {
158 m_dummyTool = KisToolDummyFactory().createTool(m_actionCollection);
159 }
160 setCurrentTool(m_dummyTool);
161 m_tools_disabled = true;
162 }
163 else if (enable && m_tools_disabled) {
164 m_tools_disabled = false;
165 if (m_oldTool) {
166 // restore the old current tool
167 setCurrentTool(m_oldTool);
168 m_oldTool = 0;
169 }
170 else {
171 m_oldTool = 0;
172 KisTool * t = findTool("tool_brush");
173 setCurrentTool(t);
174 }
175 }
176}
177
178void KisToolManager::setCurrentTool(KisTool *tool)
179{
180 KisTool *oldTool = currentTool();
181 KisCanvas * canvas = (KisCanvas*)m_controller->kiscanvas();
182
183
184 if (oldTool)
185 {
186 oldTool->deactivate();
187 oldTool->action()->setChecked( false );
188
189 m_paletteManager->removeWidget(chalk::TOOL_OPTION_WIDGET);
190 }
191
192 if (tool) {
193
194 if (!tool->optionWidget()) {
195 tool->createOptionWidget(0);
196 }
197 TQWidget * w = tool->optionWidget();
198
199 if (w)
200 m_paletteManager->addWidget(w, chalk::TOOL_OPTION_WIDGET, chalk::CONTROL_PALETTE );
201
202 m_inputDeviceToolMap[m_controller->currentInputDevice()] = tool;
203 m_controller->setCanvasCursor(tool->cursor());
204
205 canvas->enableMoveEventCompressionHint(dynamic_cast<KisToolNonPaint *>(tool) != NULL);
206
207 m_subject->notifyObservers();
208
209 tool->action()->setChecked( true );
210 tool->action()->activate();
211 m_toolBox->slotSetTool(tool->name());
212 } else {
213 m_inputDeviceToolMap[m_controller->currentInputDevice()] = 0;
214 m_controller->setCanvasCursor(KisCursor::arrowCursor());
215 }
216
217}
218
219void KisToolManager::setCurrentTool( const TQString & toolName )
220{
221 setCurrentTool(findTool(toolName));
222}
223
224KisTool * KisToolManager::currentTool() const
225{
226 InputDeviceToolMap::const_iterator it = m_inputDeviceToolMap.find(m_controller->currentInputDevice());
227
228 if (it != m_inputDeviceToolMap.end()) {
229 return (*it).second;
230 } else {
231 return 0;
232 }
233}
234
235
236void KisToolManager::setToolForInputDevice(KisInputDevice oldDevice, KisInputDevice newDevice)
237{
238 InputDeviceToolSetMap::iterator vit = m_inputDeviceToolSetMap.find(oldDevice);
239
240 if (vit != m_inputDeviceToolSetMap.end()) {
241 vKisTool& oldTools = (*vit).second;
242 for (vKisTool::iterator it = oldTools.begin(); it != oldTools.end(); ++it) {
243 KisTool *tool = *it;
244 TDEAction *toolAction = tool->action();
245 toolAction->disconnect(TQ_SIGNAL(activated()), tool, TQ_SLOT(activate()));
246 }
247 }
248 KisTool *oldTool = currentTool();
249 if (oldTool)
250 {
251 m_paletteManager->removeWidget(chalk::TOOL_OPTION_WIDGET);
252 oldTool->deactivate();
253 }
254
255
256 vit = m_inputDeviceToolSetMap.find(newDevice);
257
258 Q_ASSERT(vit != m_inputDeviceToolSetMap.end());
259
260 vKisTool& tools = (*vit).second;
261
262 for (vKisTool::iterator it = tools.begin(); it != tools.end(); ++it) {
263 KisTool *tool = *it;
264 TDEAction *toolAction = tool->action();
265 connect(toolAction, TQ_SIGNAL(activated()), tool, TQ_SLOT(activate()));
266 }
267}
268
269void KisToolManager::activateCurrentTool()
270{
271 KisTool * t = currentTool();
272 if (t && t->action()) {
273 t->action()->activate();
274 }
275}
276
277KisTool * KisToolManager::findTool(const TQString &toolName, KisInputDevice inputDevice) const
278{
279 if (inputDevice == KisInputDevice::unknown()) {
280 inputDevice = m_controller->currentInputDevice();
281 }
282
283 KisTool *tool = 0;
284
285 InputDeviceToolSetMap::const_iterator vit = m_inputDeviceToolSetMap.find(inputDevice);
286
287 Q_ASSERT(vit != m_inputDeviceToolSetMap.end());
288
289 const vKisTool& tools = (*vit).second;
290
291 for (vKisTool::const_iterator it = tools.begin(); it != tools.end(); ++it) {
292 KisTool *t = *it;
293 if (t->name() == toolName) {
294 tool = t;
295 break;
296 }
297 }
298
299 return tool;
300}
301
302
303#include "kis_tool_manager.moc"
Interface for classes that implement a canvas; i.e., a widget where KisImages are painted onto.
KisCanvasSubject is part of the Observer pattern.