All Classes Namespaces Functions Variables Enumerations Properties Pages
viewmanager.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 
18 #include <QPainterPath>
19 #include "viewmanager.h"
20 #include "editor.h"
21 #include "object.h"
22 #include "camera.h"
23 #include "layercamera.h"
24 
25 const static qreal mMinScale = 0.01;
26 const static qreal mMaxScale = 100.0;
27 
28 const std::vector<qreal> gZoomLevels
29 {
30  0.01, 0.02, 0.04, 0.06, 0.08, 0.12,
31  0.16, 0.25, 0.33, 0.5, 0.75, 1.0,
32  1.5, 2.0, 3.0, 4.0, 5.0, 6.0,
33  8.0, 16.0, 32.0, 48.0, 64.0, 96.0
34 };
35 
36 
37 ViewManager::ViewManager(Editor* editor) : BaseManager(editor)
38 {
39  mDefaultEditorCamera = new Camera;
40  mCurrentCamera = mDefaultEditorCamera;
41 }
42 
43 ViewManager::~ViewManager() {
44  delete mDefaultEditorCamera;
45 }
46 
47 bool ViewManager::init()
48 {
49  connect(editor(), &Editor::currentFrameChanged, this, &ViewManager::onCurrentFrameChanged);
50  return true;
51 }
52 
53 Status ViewManager::load(Object*)
54 {
55  mCameraLayer = nullptr;
56  mCurrentCamera = mDefaultEditorCamera;
57  mCurrentCamera->reset();
58  updateViewTransforms();
59 
60  return Status::OK;
61 }
62 
63 Status ViewManager::save(Object* o)
64 {
65  o->data()->setCurrentView(mView);
66  return Status::OK;
67 }
68 
69 void ViewManager::workingLayerChanged(Layer* layer)
70 {
71  if (layer->type() == Layer::CAMERA)
72  {
73  setCameraLayer(layer);
74  }
75  else
76  {
77  setCameraLayer(nullptr);
78  }
79 }
80 
81 QPointF ViewManager::mapCanvasToScreen(QPointF p) const
82 {
83  return mViewCanvas.map(p);
84 }
85 
86 QPointF ViewManager::mapScreenToCanvas(QPointF p) const
87 {
88  return mViewCanvasInverse.map(p);
89 }
90 
91 QPainterPath ViewManager::mapCanvasToScreen(const QPainterPath& path) const
92 {
93  return mViewCanvas.map(path);
94 }
95 
96 QRectF ViewManager::mapCanvasToScreen(const QRectF& rect) const
97 {
98  return mViewCanvas.mapRect(rect);
99 }
100 
101 QRectF ViewManager::mapScreenToCanvas(const QRectF& rect) const
102 {
103  return mViewCanvasInverse.mapRect(rect);
104 }
105 
106 QPolygonF ViewManager::mapPolygonToScreen(const QPolygonF &polygon) const
107 {
108  return mViewCanvas.map(polygon);
109 }
110 
111 QPolygonF ViewManager::mapPolygonToCanvas(const QPolygonF &polygon) const
112 {
113  return mViewCanvasInverse.map(polygon);
114 }
115 
116 QPainterPath ViewManager::mapScreenToCanvas(const QPainterPath& path) const
117 {
118  return mViewCanvasInverse.map(path);
119 }
120 
121 QTransform ViewManager::getView() const
122 {
123  return mViewCanvas;
124 }
125 
126 QTransform ViewManager::getViewInverse() const
127 {
128  return mViewCanvasInverse;
129 }
130 
131 void ViewManager::updateViewTransforms()
132 {
133  if (mCameraLayer)
134  {
135  int frame = editor()->currentFrame();
136  mCurrentCamera = mCameraLayer->getCameraAtFrame(frame);
137  if (mCurrentCamera)
138  {
139  mCurrentCamera->updateViewTransform();
140  }
141  mView = mCameraLayer->getViewAtFrame(frame);
142  }
143  else
144  {
145  mCurrentCamera = mDefaultEditorCamera;
146  mCurrentCamera->updateViewTransform();
147 
148  mView = mCurrentCamera->getView();
149  }
150 
151  mViewInverse = mView.inverted();
152 
153  float flipX = mIsFlipHorizontal ? -1.f : 1.f;
154  float flipY = mIsFlipVertical ? -1.f : 1.f;
155  QTransform f = QTransform::fromScale(static_cast<qreal>(flipX), static_cast<qreal>(flipY));
156 
157  mViewCanvas = mView * f * mCentre;
158  mViewCanvasInverse = mViewCanvas.inverted();
159 }
160 
161 QPointF ViewManager::translation() const
162 {
163  if (mCurrentCamera)
164  {
165  return mCurrentCamera->translation();
166  }
167  return QPointF(0, 0);
168 }
169 
170 void ViewManager::translate(float dx, float dy)
171 {
172  if (mCurrentCamera)
173  {
174  mCurrentCamera->translate(static_cast<qreal>(dx), static_cast<qreal>(dy));
175  updateViewTransforms();
176 
177  emit viewChanged();
178  }
179 }
180 
181 void ViewManager::translate(QPointF offset)
182 {
183  translate(static_cast<float>(offset.x()), static_cast<float>(offset.y()));
184 }
185 
186 void ViewManager::centerView()
187 {
188  translate(0, 0);
189 }
190 
191 float ViewManager::rotation()
192 {
193  if (mCurrentCamera)
194  {
195  return static_cast<float>(mCurrentCamera->rotation());
196  }
197  return 0.0f;
198 }
199 
200 void ViewManager::rotate(float degree)
201 {
202  if (mCurrentCamera)
203  {
204  mCurrentCamera->rotate(static_cast<qreal>(degree));
205  updateViewTransforms();
206 
207  emit viewChanged();
208  }
209 }
210 
211 void ViewManager::resetRotation()
212 {
213  rotate(0);
214 }
215 
216 qreal ViewManager::scaling()
217 {
218  if (mCurrentCamera)
219  {
220  return mCurrentCamera->scaling();
221  }
222  return 0.0;
223 }
224 
225 void ViewManager::scaleUp()
226 {
227  for (size_t i = 0; i < gZoomLevels.size(); i++)
228  {
229  if (gZoomLevels[i] > scaling())
230  {
231  scale(gZoomLevels[i]);
232  return;
233  }
234  }
235 
236  // out of pre-defined zoom levels
237  scale(scaling() * 1.18);
238 }
239 
240 void ViewManager::scaleDown()
241 {
242  for (int i = static_cast<int>(gZoomLevels.size()) - 1; i >= 0; --i)
243  {
244  if (gZoomLevels[static_cast<unsigned>(i)] < scaling())
245  {
246  scale(gZoomLevels[static_cast<unsigned>(i)]);
247  return;
248  }
249  }
250  scale(scaling() * 0.8333);
251 }
252 
253 void ViewManager::scale100()
254 {
255  scale(1.0);
256 }
257 
258 void ViewManager::scale400()
259 {
260  scale(4.0);
261 }
262 
263 void ViewManager::scale300()
264 {
265  scale(3.0);
266 }
267 
268 void ViewManager::scale200()
269 {
270  scale(2.0);
271 }
272 
273 void ViewManager::scale50()
274 {
275  scale(0.5);
276 }
277 
278 void ViewManager::scale33()
279 {
280  scale(0.33);
281 }
282 
283 void ViewManager::scale25()
284 {
285  scale(0.25);
286 }
287 
288 void ViewManager::scale(qreal scaleValue)
289 {
290  if (scaleValue < mMinScale)
291  {
292  scaleValue = mMinScale;
293  }
294  else if (scaleValue > mMaxScale)
295  {
296  scaleValue = mMaxScale;
297  }
298 
299  if (mCurrentCamera)
300  {
301  mCurrentCamera->scale(scaleValue);
302  updateViewTransforms();
303 
304  emit viewChanged();
305  }
306 }
307 
308 void ViewManager::scaleWithOffset(qreal scaleValue, QPointF offset)
309 {
310  if (scaleValue < mMinScale)
311  {
312  scaleValue = mMinScale;
313  }
314  else if (scaleValue > mMaxScale)
315  {
316  scaleValue = mMaxScale;
317  }
318 
319  if (mCurrentCamera)
320  {
321  mCurrentCamera->scaleWithOffset(scaleValue, offset);
322  updateViewTransforms();
323 
324  emit viewChanged();
325  }
326 }
327 
328 void ViewManager::flipHorizontal(bool b)
329 {
330  if (b != mIsFlipHorizontal)
331  {
332  mIsFlipHorizontal = b;
333  updateViewTransforms();
334 
335  emit viewChanged();
336  emit viewFlipped();
337  }
338 }
339 
340 void ViewManager::flipVertical(bool b)
341 {
342  if (b != mIsFlipVertical)
343  {
344  mIsFlipVertical = b;
345  updateViewTransforms();
346 
347  emit viewChanged();
348  emit viewFlipped();
349  }
350 }
351 
352 void ViewManager::setOverlayCenter(bool b)
353 {
354  if (b != mOverlayCenter)
355  {
356  mOverlayCenter = b;
357  updateViewTransforms();
358  emit viewChanged();
359  }
360 }
361 
362 void ViewManager::setOverlayThirds(bool b)
363 {
364  if (b != mOverlayThirds)
365  {
366  mOverlayThirds = b;
367  updateViewTransforms();
368  emit viewChanged();
369  }
370 }
371 
372 void ViewManager::setOverlayGoldenRatio(bool b)
373 {
374  if (b != mOverlayGoldenRatio)
375  {
376  mOverlayGoldenRatio = b;
377  updateViewTransforms();
378  emit viewChanged();
379  }
380 }
381 
382 void ViewManager::setOverlaySafeAreas(bool b)
383 {
384  if (b != mOverlaySafeAreas)
385  {
386  mOverlaySafeAreas = b;
387  updateViewTransforms();
388  emit viewChanged();
389  }
390 }
391 
392 void ViewManager::setCanvasSize(QSize size)
393 {
394  mCanvasSize = size;
395  mCentre = QTransform::fromTranslate(mCanvasSize.width() / 2., mCanvasSize.height() / 2.);
396 
397  updateViewTransforms();
398  emit viewChanged();
399 }
400 
401 void ViewManager::setCameraLayer(Layer* layer)
402 {
403  if (layer != nullptr)
404  {
405  if (layer->type() != Layer::CAMERA)
406  {
407  Q_ASSERT(false && "Only camera layers allowed pls");
408  return;
409  }
410  mCameraLayer = static_cast<LayerCamera*>(layer);
411  }
412  else
413  {
414  mCameraLayer = nullptr;
415  }
416 
417  updateViewTransforms();
418 }
419 
420 void ViewManager::onCurrentFrameChanged()
421 {
422  if (mCameraLayer)
423  {
424  updateViewTransforms();
425  }
426 }
427 
428 void ViewManager::resetView()
429 {
430  if (mCurrentCamera)
431  {
432  mCurrentCamera->reset();
433  updateViewTransforms();
434  emit viewChanged();
435  emit viewFlipped();
436  }
437 }
QTransform fromTranslate(qreal dx, qreal dy)
QTransform fromScale(qreal sx, qreal sy)
int width() const const
QPoint map(const QPoint &point) const const
Definition: camera.h:24
QTransform inverted(bool *invertible) const const
qreal x() const const
qreal y() const const
Definition: layer.h:39
int height() const const
Definition: object.h:54
Definition: editor.h:51
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QRect mapRect(const QRect &rectangle) const const