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
layermanager.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 "layermanager.h"
19
20#include "object.h"
21#include "editor.h"
22
23#include "layersound.h"
24#include "layerbitmap.h"
25#include "layervector.h"
26#include "layercamera.h"
27
28#include <QDebug>
29
30LayerManager::LayerManager(Editor* editor) : BaseManager(editor, __FUNCTION__)
31{
32}
33
34LayerManager::~LayerManager()
35{
36}
37
38bool LayerManager::init()
39{
40 return true;
41}
42
43Status LayerManager::load(Object*)
44{
45 mLastCameraLayerIdx = 0;
46 // Do not emit layerCountChanged here because the editor has not updated to this object yet
47 // Leave that to the caller of this function
48 return Status::OK;
49}
50
51Status LayerManager::save(Object* o)
52{
53 o->data()->setCurrentLayer(editor()->currentLayerIndex());
54 return Status::OK;
55}
56
57LayerCamera* LayerManager::getCameraLayerBelow(int layerIndex) const
58{
59 return static_cast<LayerCamera*>(object()->getLayerBelow(layerIndex, Layer::CAMERA));
60}
61
62Layer* LayerManager::getLastCameraLayer()
63{
64 Layer* layer = object()->getLayer(mLastCameraLayerIdx);
65 if (layer->type() == Layer::CAMERA)
66 {
67 return layer;
68 }
69
70 // it's not a camera layer
71 std::vector<LayerCamera*> camLayers = object()->getLayersByType<LayerCamera>();
72 if (camLayers.size() > 0)
73 {
74 return camLayers[0];
75 }
76 return nullptr;
77}
78
79Layer* LayerManager::currentLayer()
80{
81 Layer* layer = currentLayer(0);
82 Q_ASSERT(layer != nullptr);
83 return layer;
84}
85
86Layer* LayerManager::currentLayer(int incr)
87{
88 Q_ASSERT(object() != nullptr);
89 return object()->getLayer(editor()->currentLayerIndex() + incr);
90}
91
92Layer* LayerManager::getLayer(int index)
93{
94 Q_ASSERT(object() != nullptr);
95 return object()->getLayer(index);
96}
97
98Layer* LayerManager::findLayerByName(QString sName, Layer::LAYER_TYPE type)
99{
100 return object()->findLayerByName(sName, type);
101}
102
103Layer* LayerManager::findLayerById(int layerId)
104{
105 return object()->findLayerById(layerId);
106}
107
108int LayerManager::currentLayerIndex()
109{
110 return editor()->currentLayerIndex();
111}
112
113void LayerManager::setCurrentLayer(int layerIndex)
114{
115 Q_ASSERT(layerIndex >= 0);
116 Q_ASSERT(layerIndex < object()->getLayerCount());
117
118 // Deselect frames of previous layer.
119 Layer* previousLayer = currentLayer();
120 if (previousLayer != object()->getLayer(layerIndex)) {
121 previousLayer->deselectAll();
122 }
123
124 emit currentLayerWillChange(layerIndex);
125
126 // Do not check if layer index has changed
127 // because the current layer may have changed either way
128 editor()->setCurrentLayerIndex(layerIndex);
129 emit currentLayerChanged(layerIndex);
130
131 if (object()->getLayer(layerIndex)->type() == Layer::CAMERA)
132 {
133 mLastCameraLayerIdx = layerIndex;
134 }
135}
136
137void LayerManager::setCurrentLayer(Layer* layer)
138{
139 setCurrentLayer(getIndex(layer));
140}
141
142void LayerManager::gotoNextLayer()
143{
144 if (editor()->currentLayerIndex() < object()->getLayerCount() - 1)
145 {
146 currentLayer()->deselectAll();
147 editor()->setCurrentLayerIndex(editor()->currentLayerIndex() + 1);
148 emit currentLayerChanged(editor()->currentLayerIndex());
149 }
150}
151
152void LayerManager::gotoPreviouslayer()
153{
154 if (editor()->currentLayerIndex() > 0)
155 {
156 currentLayer()->deselectAll();
157 editor()->setCurrentLayerIndex(editor()->currentLayerIndex() - 1);
158 emit currentLayerChanged(editor()->currentLayerIndex());
159 }
160}
161
162QString LayerManager::nameSuggestLayer(const QString& name)
163{
164 // if no layers: return name
165 if (count() == 0)
166 {
167 return name;
168 }
169 QVector<QString> sLayers;
170 // fill Vector with layer names
171 for (int i = 0; i < count(); i++)
172 {
173 sLayers.append(getLayer(i)->name());
174 }
175 // if name is not in list, return name
176 if (!sLayers.contains(name))
177 {
178 return name;
179 }
180 int newIndex = 2;
181 QString newName = name;
182 do {
183 newName = QStringLiteral("%1 %2")
184 .arg(name).arg(QString::number(newIndex++));
185 } while (sLayers.contains(newName));
186 return newName;
187}
188
189Layer* LayerManager::createLayer(Layer::LAYER_TYPE type, const QString& strLayerName)
190{
191 Layer* layer = nullptr;
192 switch (type) {
193 case Layer::BITMAP:
194 layer = object()->addNewBitmapLayer();
195 break;
196 case Layer::VECTOR:
197 layer = object()->addNewVectorLayer();
198 break;
199 case Layer::SOUND:
200 layer = object()->addNewSoundLayer();
201 break;
202 case Layer::CAMERA:
203 layer = object()->addNewCameraLayer();
204 break;
205 default:
206 Q_ASSERT(true);
207 return nullptr;
208 }
209
210 layer->setName(strLayerName);
211 emit layerCountChanged(count());
212 setCurrentLayer(getLastLayerIndex());
213
214 return layer;
215}
216
217LayerBitmap* LayerManager::createBitmapLayer(const QString& strLayerName)
218{
219 LayerBitmap* layer = object()->addNewBitmapLayer();
220 layer->setName(strLayerName);
221
222 emit layerCountChanged(count());
223 setCurrentLayer(getLastLayerIndex());
224
225 return layer;
226}
227
228LayerVector* LayerManager::createVectorLayer(const QString& strLayerName)
229{
230 LayerVector* layer = object()->addNewVectorLayer();
231 layer->setName(strLayerName);
232
233 emit layerCountChanged(count());
234 setCurrentLayer(getLastLayerIndex());
235
236 return layer;
237}
238
239LayerCamera* LayerManager::createCameraLayer(const QString& strLayerName)
240{
241 LayerCamera* layer = object()->addNewCameraLayer();
242 layer->setName(strLayerName);
243
244 emit layerCountChanged(count());
245 setCurrentLayer(getLastLayerIndex());
246
247 return layer;
248}
249
250LayerSound* LayerManager::createSoundLayer(const QString& strLayerName)
251{
252 LayerSound* layer = object()->addNewSoundLayer();
253 layer->setName(strLayerName);
254
255 emit layerCountChanged(count());
256 setCurrentLayer(getLastLayerIndex());
257
258 return layer;
259}
260
261int LayerManager::lastFrameAtFrame(int frameIndex)
262{
263 Object* o = object();
264 for (int i = frameIndex; i >= 0; i -= 1)
265 {
266 for (int layerIndex = 0; layerIndex < o->getLayerCount(); ++layerIndex)
267 {
268 auto pLayer = o->getLayer(layerIndex);
269 if (pLayer->keyExists(i))
270 {
271 return i;
272 }
273 }
274 }
275 return -1;
276}
277
278int LayerManager::firstKeyFrameIndex()
279{
280 int minPosition = INT_MAX;
281
282 Object* o = object();
283 for (int i = 0; i < o->getLayerCount(); ++i)
284 {
285 Layer* pLayer = o->getLayer(i);
286
287 int position = pLayer->firstKeyFramePosition();
288 if (position < minPosition)
289 {
290 minPosition = position;
291 }
292 }
293 return minPosition;
294}
295
296int LayerManager::lastKeyFrameIndex()
297{
298 int maxPosition = 0;
299
300 for (int i = 0; i < object()->getLayerCount(); ++i)
301 {
302 Layer* pLayer = object()->getLayer(i);
303
304 int position = pLayer->getMaxKeyFramePosition();
305 if (position > maxPosition)
306 {
307 maxPosition = position;
308 }
309 }
310 return maxPosition;
311}
312
313int LayerManager::count()
314{
315 return object()->getLayerCount();
316}
317
318bool LayerManager::canDeleteLayer(int index) const
319{
320 return object()->canDeleteLayer(index);
321}
322
323Status LayerManager::deleteLayer(int index)
324{
325 Layer* layer = object()->getLayer(index);
326 if (layer->type() == Layer::CAMERA)
327 {
328 std::vector<LayerCamera*> camLayers = object()->getLayersByType<LayerCamera>();
329 if (camLayers.size() == 1)
330 return Status::ERROR_NEED_AT_LEAST_ONE_CAMERA_LAYER;
331 }
332 Q_ASSERT(object()->getLayerCount() >= 2);
333
334 // current layer is the last layer && we are deleting it
335 if (index == object()->getLayerCount() - 1 &&
336 index == currentLayerIndex())
337 {
338 setCurrentLayer(currentLayerIndex() - 1);
339 }
340 object()->deleteLayer(layer);
341 if (index >= currentLayerIndex())
342 {
343 // current layer has changed, so trigger updates
344 setCurrentLayer(currentLayerIndex());
345 }
346
347 emit layerDeleted(index);
348 emit layerCountChanged(count());
349
350 return Status::OK;
351}
352
353Status LayerManager::renameLayer(Layer* layer, const QString& newName)
354{
355 if (newName.isEmpty()) return Status::FAIL;
356
357 layer->setName(newName);
358 emit currentLayerChanged(getIndex(layer));
359 return Status::OK;
360}
361
362void LayerManager::notifyLayerChanged(Layer* layer)
363{
364 emit currentLayerChanged(getIndex(layer));
365}
366
371int LayerManager::animationLength(bool includeSounds)
372{
373 int maxFrame = -1;
374
375 Object* o = object();
376 for (int i = 0; i < o->getLayerCount(); i++)
377 {
378 if (o->getLayer(i)->type() == Layer::SOUND)
379 {
380 if (!includeSounds)
381 continue;
382
383 Layer* soundLayer = o->getLayer(i);
384 soundLayer->foreachKeyFrame([&maxFrame](KeyFrame* keyFrame)
385 {
386 int endPosition = keyFrame->pos() + (keyFrame->length() - 1);
387 if (endPosition > maxFrame)
388 {
389 maxFrame = endPosition;
390 }
391 });
392 }
393 else
394 {
395 int lastFramePos = o->getLayer(i)->getMaxKeyFramePosition();
396 if (lastFramePos > maxFrame)
397 {
398 maxFrame = lastFramePos;
399 }
400 }
401 }
402 return maxFrame;
403}
404
405void LayerManager::notifyAnimationLengthChanged()
406{
407 emit animationLengthChanged(animationLength(true));
408}
409
410int LayerManager::getIndex(Layer* layer) const
411{
412 const Object* o = object();
413 for (int i = 0; i < o->getLayerCount(); ++i)
414 {
415 if (layer == o->getLayer(i))
416 return i;
417 }
418 return -1;
419}
BaseManager
Definition: basemanager.h:29
Editor
Definition: editor.h:71
KeyFrame
Definition: keyframe.h:30
LayerBitmap
Definition: layerbitmap.h:26
LayerCamera
Definition: layercamera.h:30
Layer
Definition: layer.h:33
LayerManager::animationLength
int animationLength(bool includeSounds=true)
Get the length of current project.
Definition: layermanager.cpp:371
LayerManager::createLayer
Layer * createLayer(Layer::LAYER_TYPE type, const QString &strLayerName)
Returns a new Layer with the given LAYER_TYPE.
Definition: layermanager.cpp:189
LayerManager::notifyAnimationLengthChanged
void notifyAnimationLengthChanged()
This should be emitted whenever the animation length frames, eg.
Definition: layermanager.cpp:405
LayerSound
Definition: layersound.h:26
LayerVector
Definition: layervector.h:26
Object
Definition: object.h:42
Object::canDeleteLayer
bool canDeleteLayer(int index) const
Allows you to check whether the layer at the given index can be deleted.
Definition: object.cpp:341
Status
Definition: pencilerror.h:40
QString
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString::isEmpty
bool isEmpty() const const
QString::number
QString number(int n, int base)
QVector
QVector::append
void append(const T &value)
QVector::contains
bool contains(const T &value) const const
Generated on Thu Jun 5 2025 14:06:43 for Pencil2D by doxygen 1.9.6 based on revision 4c63407997b2c03e5048716586dec6fbbb755173