All Classes Namespaces Functions Variables Enumerations Properties Pages
toolmanager.cpp
1 /*
2 
3 Pencil2D - Traditional Animation Software
4 Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon
5 Copyright (C) 2012-2020 Matthew Chiawen Chang
6 
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; version 2 of the License.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 */
17 #include "toolmanager.h"
18 
19 #include <cmath>
20 #include "pentool.h"
21 #include "penciltool.h"
22 #include "brushtool.h"
23 #include "buckettool.h"
24 #include "erasertool.h"
25 #include "eyedroppertool.h"
26 #include "handtool.h"
27 #include "movetool.h"
28 #include "polylinetool.h"
29 #include "selecttool.h"
30 #include "smudgetool.h"
31 #include "editor.h"
32 
33 
34 ToolManager::ToolManager(Editor* editor) : BaseManager(editor, __FUNCTION__)
35 {
36 }
37 
38 bool ToolManager::init()
39 {
40  mToolSetHash.insert(PEN, new PenTool(this));
41  mToolSetHash.insert(PENCIL, new PencilTool(this));
42  mToolSetHash.insert(BRUSH, new BrushTool(this));
43  mToolSetHash.insert(ERASER, new EraserTool(this));
44  mToolSetHash.insert(BUCKET, new BucketTool(this));
45  mToolSetHash.insert(EYEDROPPER, new EyedropperTool(this));
46  mToolSetHash.insert(HAND, new HandTool(this));
47  mToolSetHash.insert(MOVE, new MoveTool(this));
48  mToolSetHash.insert(POLYLINE, new PolylineTool(this));
49  mToolSetHash.insert(SELECT, new SelectTool(this));
50  mToolSetHash.insert(SMUDGE, new SmudgeTool(this));
51 
52  foreach(BaseTool* pTool, mToolSetHash.values())
53  {
54  pTool->initialize(editor());
55  }
56 
57  setDefaultTool();
58 
59  return true;
60 }
61 
62 Status ToolManager::load(Object*)
63 {
64  return Status::OK;
65 }
66 
67 Status ToolManager::save(Object*)
68 {
69  return Status::OK;
70 }
71 
72 BaseTool* ToolManager::currentTool()
73 {
74  if (mTemporaryTool != nullptr)
75  {
76  return mTemporaryTool;
77  }
78  else if (mTabletEraserTool != nullptr)
79  {
80  return mTabletEraserTool;
81  }
82  return mCurrentTool;
83 }
84 
85 BaseTool* ToolManager::getTool(ToolType eToolType)
86 {
87  return mToolSetHash[eToolType];
88 }
89 
90 void ToolManager::setDefaultTool()
91 {
92  // Set default tool
93  // (called by the main window init)
94  ToolType defaultToolType = PENCIL;
95 
96  setCurrentTool(defaultToolType);
97  mTabletEraserTool = nullptr;
98  mTemporaryTool = nullptr;
99 }
100 
101 void ToolManager::setCurrentTool(ToolType eToolType)
102 {
103  if (mCurrentTool != nullptr)
104  {
105  mCurrentTool->leavingThisTool();
106  }
107 
108  mCurrentTool = getTool(eToolType);
109  if (mTemporaryTool == nullptr && mTabletEraserTool == nullptr)
110  {
111  emit toolChanged(eToolType);
112  }
113 }
114 
115 bool ToolManager::leavingThisTool()
116 {
117  return currentTool()->leavingThisTool();
118 }
119 
120 void ToolManager::cleanupAllToolsData()
121 {
122  foreach(BaseTool* tool, mToolSetHash)
123  {
124  tool->clearToolData();
125  }
126 }
127 
128 void ToolManager::resetAllTools()
129 {
130  // Reset can be useful to solve some pencil settings problems.
131  // Beta-testers should be recommended to reset before sending tool related issues.
132  // This can prevent from users to stop working on their project.
133 
134  foreach(BaseTool* tool, mToolSetHash)
135  {
136  tool->resetToDefault();
137  }
138  qDebug("tools restored to default settings");
139 }
140 
141 void ToolManager::setWidth(float newWidth)
142 {
143  if (std::isnan(newWidth) || newWidth < 0)
144  {
145  newWidth = 1.f;
146  }
147 
148  currentTool()->setWidth(static_cast<qreal>(newWidth));
149  emit penWidthValueChanged(newWidth);
150  emit toolPropertyChanged(currentTool()->type(), WIDTH);
151 }
152 
153 void ToolManager::setFeather(float newFeather)
154 {
155  if (std::isnan(newFeather) || newFeather < 0)
156  {
157  newFeather = 0.f;
158  }
159 
160  currentTool()->setFeather(static_cast<qreal>(newFeather));
161  emit penFeatherValueChanged(newFeather);
162  emit toolPropertyChanged(currentTool()->type(), FEATHER);
163 }
164 
165 void ToolManager::setUseFeather(bool usingFeather)
166 {
167  int usingAA = currentTool()->properties.useAA;
168  int value = propertySwitch(usingFeather, usingAA);
169 
170  currentTool()->setAA(value);
171  currentTool()->setUseFeather(usingFeather);
172  emit toolPropertyChanged(currentTool()->type(), USEFEATHER);
173  emit toolPropertyChanged(currentTool()->type(), ANTI_ALIASING);
174 }
175 
176 void ToolManager::setInvisibility(bool isInvisible)
177 {
178  currentTool()->setInvisibility(isInvisible);
179  emit toolPropertyChanged(currentTool()->type(), INVISIBILITY);
180 }
181 
182 void ToolManager::setPreserveAlpha(bool isPreserveAlpha)
183 {
184  currentTool()->setPreserveAlpha(isPreserveAlpha);
185  emit toolPropertyChanged(currentTool()->type(), PRESERVEALPHA);
186 }
187 
188 void ToolManager::setVectorMergeEnabled(bool isVectorMergeEnabled)
189 {
190  currentTool()->setVectorMergeEnabled(isVectorMergeEnabled);
191  emit toolPropertyChanged(currentTool()->type(), VECTORMERGE);
192 }
193 
194 void ToolManager::setBezier(bool isBezierOn)
195 {
196  currentTool()->setBezier(isBezierOn);
197  emit toolPropertyChanged(currentTool()->type(), BEZIER);
198 }
199 
200 void ToolManager::setPressure(bool isPressureOn)
201 {
202  currentTool()->setPressure(isPressureOn);
203  emit toolPropertyChanged(currentTool()->type(), PRESSURE);
204 }
205 
206 void ToolManager::setAA(int usingAA)
207 {
208  currentTool()->setAA(usingAA);
209  emit toolPropertyChanged(currentTool()->type(), ANTI_ALIASING);
210 }
211 
212 void ToolManager::setFillMode(int mode)
213 {
214  currentTool()->setFillMode(mode);
215  emit toolPropertyChanged(currentTool()->type(), FILL_MODE);
216 }
217 
218 void ToolManager::setStabilizerLevel(int level)
219 {
220  currentTool()->setStabilizerLevel(level);
221  emit toolPropertyChanged(currentTool()->type(), STABILIZATION);
222 }
223 
224 void ToolManager::setTolerance(int newTolerance)
225 {
226  newTolerance = qMax(0, newTolerance);
227 
228  currentTool()->setTolerance(newTolerance);
229  emit toleranceValueChanged(newTolerance);
230  emit toolPropertyChanged(currentTool()->type(), TOLERANCE);
231 }
232 
233 void ToolManager::setBucketColorToleranceEnabled(bool enabled)
234 {
235  currentTool()->setToleranceEnabled(enabled);
236  emit toolPropertyChanged(currentTool()->type(), USETOLERANCE);
237 }
238 
239 void ToolManager::setBucketFillExpandEnabled(bool expandValue)
240 {
241  currentTool()->setFillExpandEnabled(expandValue);
242  emit toolPropertyChanged(currentTool()->type(), USEBUCKETFILLEXPAND);
243 }
244 
245 void ToolManager::setBucketFillExpand(int expandValue)
246 {
247  currentTool()->setFillExpand(expandValue);
248  emit toolPropertyChanged(currentTool()->type(), BUCKETFILLEXPAND);
249 }
250 
251 void ToolManager::setBucketFillToLayer(int layerIndex)
252 {
253  currentTool()->setFillToLayer(layerIndex);
254  emit toolPropertyChanged(currentTool()->type(), BUCKETFILLLAYERMODE);
255 }
256 
257 void ToolManager::setBucketFillReferenceMode(int referenceMode)
258 {
259  currentTool()->setFillReferenceMode(referenceMode);
260  emit toolPropertyChanged(currentTool()->type(), BUCKETFILLLAYERREFERENCEMODE);
261 }
262 
263 void ToolManager::setUseFillContour(bool useFillContour)
264 {
265  currentTool()->setUseFillContour(useFillContour);
266  emit toolPropertyChanged(currentTool()->type(), FILLCONTOUR);
267 }
268 
269 void ToolManager::setShowSelectionInfo(bool b)
270 {
271  currentTool()->setShowSelectionInfo(b);
272 }
273 
274 // Switches on/off two actions
275 // eg. if x = true, then y = false
276 int ToolManager::propertySwitch(bool condition, int tool)
277 {
278  int value = 0;
279  int newValue = 0;
280 
281  if (condition == true)
282  {
283  value = -1;
284  newValue = mOldValue;
285  mOldValue = tool;
286  }
287  else if (condition == false)
288  {
289  value = (newValue == 1) ? 1 : mOldValue;
290  }
291  return value;
292 }
293 
294 void ToolManager::tabletSwitchToEraser()
295 {
296  mTabletEraserTool = getTool(ERASER);
297  if (mTemporaryTool == nullptr)
298  {
299  emit toolChanged(ERASER);
300  }
301 }
302 
303 void ToolManager::tabletRestorePrevTool()
304 {
305  mTabletEraserTool = nullptr;
306  if (mTemporaryTool == nullptr)
307  {
308  emit toolChanged(currentTool()->type());
309  }
310 }
311 
312 bool ToolManager::setTemporaryTool(ToolType eToolType, QFlags<Qt::Key> keys, Qt::KeyboardModifiers modifiers)
313 {
314  if (mTemporaryTool != nullptr) return false;
315  mTemporaryTriggerKeys = keys;
316  mTemporaryTriggerModifiers = modifiers;
317  mTemporaryTriggerMouseButtons = Qt::NoButton;
318  setTemporaryTool(eToolType);
319  return true;
320 }
321 
322 bool ToolManager::setTemporaryTool(ToolType eToolType, Qt::MouseButtons buttons)
323 {
324  if (mTemporaryTool != nullptr) return false;
325  mTemporaryTriggerKeys = {};
326  mTemporaryTriggerModifiers = Qt::NoModifier;
327  mTemporaryTriggerMouseButtons = buttons;
328  setTemporaryTool(eToolType);
329  return true;
330 }
331 
332 bool ToolManager::tryClearTemporaryTool(Qt::Key key)
333 {
335  switch(key)
336  {
337  case Qt::Key_Control:
338  modifier = Qt::ControlModifier;
339  break;
340  case Qt::Key_Shift:
341  modifier = Qt::ShiftModifier;
342  break;
343  case Qt::Key_Alt:
344  modifier = Qt::AltModifier;
345  break;
346  case Qt::Key_Meta:
347  modifier = Qt::MetaModifier;
348  break;
349  default:
350  break;
351  }
352 
353  if (mTemporaryTriggerKeys.testFlag(key) ||
354  mTemporaryTriggerModifiers.testFlag(modifier))
355  {
356  clearTemporaryTool();
357  return true;
358  }
359  return false;
360 }
361 
362 bool ToolManager::tryClearTemporaryTool(Qt::MouseButton button)
363 {
364  if (mTemporaryTriggerMouseButtons != Qt::NoButton && mTemporaryTriggerMouseButtons.testFlag(button))
365  {
366  clearTemporaryTool();
367  return true;
368  }
369  return false;
370 }
371 
372 void ToolManager::setTemporaryTool(ToolType eToolType)
373 {
374  mTemporaryTool = getTool(eToolType);
375  emit toolChanged(eToolType);
376 }
377 
378 void ToolManager::clearTemporaryTool()
379 {
380  mTemporaryTool = nullptr;
381  mTemporaryTriggerKeys = {};
382  mTemporaryTriggerModifiers = Qt::NoModifier;
383  mTemporaryTriggerMouseButtons = Qt::NoButton;
384  emit toolChanged(currentTool()->type());
385 }
typedef KeyboardModifiers
QHash::iterator insert(const Key &key, const T &value)
NoButton
QList< T > values() const const
Definition: object.h:41
Definition: editor.h:55
bool testFlag(Enum flag) const const