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