Pencil2D Animation
Download Community News Docs Contribute
  • Overview
  • Articles
  • Code
  •  
  • Class List
  • Class Index
  • Class Hierarchy
  • Class Members
  • File List
Loading...
Searching...
No Matches
  • core_lib
  • src
  • managers
viewmanager.cpp
1/*
2
3Pencil2D - Traditional Animation Software
4Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon
5Copyright (C) 2012-2020 Matthew Chiawen Chang
6
7This program is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; version 2 of the License.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU 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
23const static qreal mMinScale = 0.01;
24const static qreal mMaxScale = 100.0;
25
26const std::vector<qreal> gZoomLevels
27{
28 0.01, 0.02, 0.04, 0.06, 0.08, 0.12,
29 0.16, 0.25, 0.33, 0.5, 0.75, 1.0,
30 1.5, 2.0, 3.0, 4.0, 5.0, 6.0,
31 8.0, 16.0, 32.0, 48.0, 64.0, 96.0
32};
33
34
35ViewManager::ViewManager(Editor* editor) : BaseManager(editor, __FUNCTION__)
36{
37}
38
39ViewManager::~ViewManager() {
40}
41
42bool ViewManager::init()
43{
44 connect(editor(), &Editor::scrubbed, this, &ViewManager::onCurrentFrameChanged);
45 return true;
46}
47
48Status ViewManager::load(Object*)
49{
50 updateViewTransforms();
51
52 return Status::OK;
53}
54
55Status ViewManager::save(Object* o)
56{
57 o->data()->setCurrentView(mView);
58 return Status::OK;
59}
60
61QPointF ViewManager::mapCanvasToScreen(QPointF p) const
62{
63 return mViewCanvas.map(p);
64}
65
66QPointF ViewManager::mapScreenToCanvas(QPointF p) const
67{
68 return mViewCanvasInverse.map(p);
69}
70
71QPainterPath ViewManager::mapCanvasToScreen(const QPainterPath& path) const
72{
73 return mViewCanvas.map(path);
74}
75
76QRectF ViewManager::mapCanvasToScreen(const QRectF& rect) const
77{
78 return mViewCanvas.mapRect(rect);
79}
80
81QRectF ViewManager::mapScreenToCanvas(const QRectF& rect) const
82{
83 return mViewCanvasInverse.mapRect(rect);
84}
85
86QPolygonF ViewManager::mapPolygonToScreen(const QPolygonF &polygon) const
87{
88 return mViewCanvas.map(polygon);
89}
90
91QPolygonF ViewManager::mapPolygonToCanvas(const QPolygonF &polygon) const
92{
93 return mViewCanvasInverse.map(polygon);
94}
95
96QPainterPath ViewManager::mapScreenToCanvas(const QPainterPath& path) const
97{
98 return mViewCanvasInverse.map(path);
99}
100
101QTransform ViewManager::getView() const
102{
103 return mViewCanvas;
104}
105
106QTransform ViewManager::getViewInverse() const
107{
108 return mViewCanvasInverse;
109}
110
111qreal ViewManager::getScaleInversed() const
112{
113 return 1. / mScaling;
114}
115
116void ViewManager::updateViewTransforms()
117{
118 QTransform t;
119 t.translate(mTranslation.x(), mTranslation.y());
120
121 QTransform r;
122 r.rotate(mRotation);
123
124 QTransform s;
125 s.scale(mScaling, mScaling);
126
127 mView = t * r * s;
128 mViewInverse = mView.inverted();
129
130 float flipX = mIsFlipHorizontal ? -1.f : 1.f;
131 float flipY = mIsFlipVertical ? -1.f : 1.f;
132 QTransform f = QTransform::fromScale(static_cast<qreal>(flipX), static_cast<qreal>(flipY));
133
134 mViewCanvas = mView * f * mCentre;
135 mViewCanvasInverse = mViewCanvas.inverted();
136}
137
138QPointF ViewManager::translation() const
139{
140 return mTranslation;
141}
142
143void ViewManager::translate(float dx, float dy)
144{
145 mTranslation = QPointF(dx, dy);
146 updateViewTransforms();
147
148 emit viewChanged();
149}
150
151void ViewManager::translate(QPointF offset)
152{
153 translate(static_cast<float>(offset.x()), static_cast<float>(offset.y()));
154}
155
156void ViewManager::centerView()
157{
158 translate(0, 0);
159}
160
161float ViewManager::rotation()
162{
163 return mRotation;
164}
165
166void ViewManager::rotate(float degree)
167{
168 mRotation = degree;
169 updateViewTransforms();
170
171 emit viewChanged();
172}
173
174void ViewManager::rotateRelative(float delta)
175{
176 mRotation = mRotation + delta;
177 updateViewTransforms();
178
179 emit viewChanged();
180}
181
182void ViewManager::resetRotation()
183{
184 rotate(0);
185}
186
187qreal ViewManager::scaling()
188{
189 return mScaling;
190}
191
192void ViewManager::scaleUp()
193{
194 for (size_t i = 0; i < gZoomLevels.size(); i++)
195 {
196 if (mScaling < gZoomLevels[i])
197 {
198 scale(gZoomLevels[i]);
199 return;
200 }
201 }
202
203 scale(mScaling * 1.25);
204}
205
206void ViewManager::scaleDown()
207{
208 const size_t nZoomLevels = gZoomLevels.size();
209 for (size_t i = 1; i <= nZoomLevels; i++)
210 {
211 if (mScaling > gZoomLevels[nZoomLevels - i])
212 {
213 scale(gZoomLevels[nZoomLevels - i]);
214 return;
215 }
216 }
217
218 scale(mScaling * 0.8);
219}
220
221void ViewManager::scale100()
222{
223 scale(1.0);
224}
225
226void ViewManager::scale400()
227{
228 scale(4.0);
229}
230
231void ViewManager::scale300()
232{
233 scale(3.0);
234}
235
236void ViewManager::scale200()
237{
238 scale(2.0);
239}
240
241void ViewManager::scale50()
242{
243 scale(0.5);
244}
245
246void ViewManager::scale33()
247{
248 scale(0.33);
249}
250
251void ViewManager::scale25()
252{
253 scale(0.25);
254}
255
256void ViewManager::scale(qreal scaleValue)
257{
258 if (scaleValue < mMinScale)
259 {
260 scaleValue = mMinScale;
261 }
262 else if (scaleValue > mMaxScale)
263 {
264 scaleValue = mMaxScale;
265 }
266
267 mScaling = scaleValue;
268 updateViewTransforms();
269
270 emit viewChanged();
271}
272
273void ViewManager::scaleAtOffset(qreal scaleValue, QPointF offset)
274{
275 if (scaleValue < mMinScale)
276 {
277 scaleValue = mMinScale;
278 }
279 else if (scaleValue > mMaxScale)
280 {
281 scaleValue = mMaxScale;
282 }
283 mTranslation = (mTranslation + offset) * mScaling / scaleValue - offset;
284 mScaling = scaleValue;
285 updateViewTransforms();
286
287 emit viewChanged();
288}
289
290void ViewManager::flipHorizontal(bool b)
291{
292 if (b != mIsFlipHorizontal)
293 {
294 mIsFlipHorizontal = b;
295 updateViewTransforms();
296
297 emit viewChanged();
298 emit viewFlipped();
299 }
300}
301
302void ViewManager::flipVertical(bool b)
303{
304 if (b != mIsFlipVertical)
305 {
306 mIsFlipVertical = b;
307 updateViewTransforms();
308
309 emit viewChanged();
310 emit viewFlipped();
311 }
312}
313
314void ViewManager::setCanvasSize(QSize size)
315{
316 mCanvasSize = size;
317 mCentre = QTransform::fromTranslate(mCanvasSize.width() / 2., mCanvasSize.height() / 2.);
318
319 updateViewTransforms();
320 emit viewChanged();
321}
322
323void ViewManager::forceUpdateViewTransform()
324{
325 updateViewTransforms();
326 emit viewChanged();
327}
328
329void ViewManager::onCurrentFrameChanged()
330{
331 // emit because of potential camera interpolation changes
332 emit viewChanged();
333}
334
335void ViewManager::resetView()
336{
337 mTranslation = QPointF(0,0);
338 mScaling = 1.0;
339 mRotation = 0.0;
340
341 updateViewTransforms();
342 emit viewChanged();
343 emit viewFlipped();
344
345}
BaseManager
Definition: basemanager.h:29
Editor
Definition: editor.h:71
Editor::scrubbed
void scrubbed(int frameNumber)
This should be emitted after scrubbing.
Object
Definition: object.h:42
Status
Definition: pencilerror.h:40
ViewManager::getScaleInversed
qreal getScaleInversed() const
Definition: viewmanager.cpp:111
QObject::connect
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QPainterPath
QPointF
QPointF::x
qreal x() const const
QPointF::y
qreal y() const const
QPolygonF
QRectF
QSize
QSize::height
int height() const const
QSize::width
int width() const const
QTransform
QTransform::fromScale
QTransform fromScale(qreal sx, qreal sy)
QTransform::fromTranslate
QTransform fromTranslate(qreal dx, qreal dy)
QTransform::inverted
QTransform inverted(bool *invertible) const const
QTransform::map
QPoint map(const QPoint &point) const const
QTransform::mapRect
QRect mapRect(const QRect &rectangle) const const
QTransform::rotate
QTransform & rotate(qreal angle, Qt::Axis axis)
QTransform::scale
QTransform & scale(qreal sx, qreal sy)
QTransform::translate
QTransform & translate(qreal dx, qreal dy)
Generated on Thu May 8 2025 04:47:53 for Pencil2D by doxygen 1.9.6 based on revision 4513250b1d5b1a3676ec0e67b06b7a885ceaae39