Pencil2D  ff90c0872e88be3bf81c548cd60f01983012ec49
Pencil2D is an animation software for both bitmap and vector graphics. It is free, multi-platform, and open source.
 All Classes Functions
layer.cpp
1 /*
2 
3 Pencil - Traditional Animation Software
4 Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon
5 Copyright (C) 2012-2017 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 <climits>
19 #include <cassert>
20 #include <QtDebug>
21 #include <QInputDialog>
22 #include <QLineEdit>
23 #include "keyframe.h"
24 #include "keyframefactory.h"
25 #include "layer.h"
26 #include "object.h"
27 #include "timeline.h"
28 #include "timelinecells.h"
29 
30 // Used to sort the selected frames list
31 //
32 bool sortAsc(int left, int right)
33 {
34  return left < right;
35 }
36 
37 Layer::Layer( Object* pObject, LAYER_TYPE eType ) : QObject( pObject )
38 {
39  mObject = pObject;
40  meType = eType;
41  mName = QString( tr( "Undefined Layer" ) );
42 
43  mId = pObject->getUniqueLayerID();
44 
45  //addNewEmptyKeyAt( 1 );
46 
47  Q_ASSERT( eType != UNDEFINED );
48 }
49 
50 Layer::~Layer()
51 {
52  for ( auto pair : mKeyFrames )
53  {
54  KeyFrame* pKeyFrame = pair.second;
55  delete pKeyFrame;
56  }
57  mKeyFrames.clear();
58 }
59 
60 void Layer::foreachKeyFrame( std::function<void( KeyFrame* )> action )
61 {
62  for ( auto pair : mKeyFrames )
63  {
64  action( pair.second );
65  }
66 }
67 
68 bool Layer::keyExists( int position )
69 {
70  return ( mKeyFrames.find( position ) != mKeyFrames.end() );
71 }
72 
73 KeyFrame* Layer::getKeyFrameAt( int position )
74 {
75  auto it = mKeyFrames.find( position );
76  if ( it == mKeyFrames.end() )
77  {
78  return nullptr;
79  }
80  return it->second;
81 }
82 
83 KeyFrame* Layer::getLastKeyFrameAtPosition( int position )
84 {
85  if ( position < 1 )
86  {
87  position = 1;
88  }
89  auto it = mKeyFrames.lower_bound( position );
90  if ( it == mKeyFrames.end() )
91  {
92  return nullptr;
93  }
94  return it->second;
95 }
96 
97 int Layer::getPreviousKeyFramePosition( int position )
98 {
99  auto it = mKeyFrames.upper_bound( position );
100  if ( it == mKeyFrames.end() )
101  {
102  return firstKeyFramePosition();
103  }
104  return it->first;
105 }
106 
107 int Layer::getNextKeyFramePosition( int position )
108 {
109  auto it = mKeyFrames.lower_bound( position );
110  if ( it == mKeyFrames.end() )
111  {
112  return getMaxKeyFramePosition();
113  }
114 
115  if ( it != mKeyFrames.begin() )
116  {
117  --it;
118  }
119  return it->first;
120 }
121 
122 int Layer::getPreviousFrameNumber( int position, bool isAbsolute )
123 {
124  int prevNumber;
125 
126  if (isAbsolute) {
127  prevNumber = getPreviousKeyFramePosition(position);
128  }
129  else {
130  prevNumber = position - 1;
131  }
132 
133 
134  if (prevNumber == position)
135  {
136  return -1; // There is no previous keyframe
137  }
138  else
139  {
140  return prevNumber;
141  }
142 }
143 
144 int Layer::getNextFrameNumber( int position, bool isAbsolute )
145 {
146  int nextNumber;
147 
148  if (isAbsolute) {
149  nextNumber = getNextKeyFramePosition(position);
150  }
151  else {
152  nextNumber = position + 1;
153  }
154 
155 
156  if (nextNumber == position) {
157  return -1; // There is no next keyframe
158  }
159  else {
160  return nextNumber;
161  }
162 }
163 
164 int Layer::firstKeyFramePosition()
165 {
166  if ( !mKeyFrames.empty() )
167  {
168  return mKeyFrames.rbegin()->first; // rbegin is the lowest key frame position
169  }
170  return 0;
171 }
172 
173 int Layer::getMaxKeyFramePosition()
174 {
175  if ( !mKeyFrames.empty() )
176  {
177  return mKeyFrames.begin()->first; // begin is the highest key frame position
178  }
179  return 0;
180 }
181 
182 bool Layer::addNewEmptyKeyAt( int position )
183 {
184  if ( position <= 0 )
185  {
186  return false;
187  }
188  KeyFrame* key = KeyFrameFactory::create( meType, mObject );
189  if ( key == nullptr )
190  {
191  return false;
192  }
193  return addKeyFrame( position, key );
194 }
195 
196 bool Layer::addKeyFrame( int position, KeyFrame* pKeyFrame )
197 {
198  auto it = mKeyFrames.find( position );
199  if ( it != mKeyFrames.end() )
200  {
201  return false;
202  }
203 
204  pKeyFrame->setPos( position );
205  mKeyFrames.insert( std::make_pair( position, pKeyFrame ) );
206 
207  return true;
208 }
209 
210 bool Layer::removeKeyFrame( int position )
211 {
212  auto frame = getKeyFrameWhichCovers(position);
213  if(frame)
214  {
215  mKeyFrames.erase(frame->pos());
216  delete frame;
217  }
218 
219  return true;
220 }
221 
222 bool Layer::moveKeyFrameForward( int position )
223 {
224  return swapKeyFrames( position, position + 1 );
225 }
226 
227 bool Layer::moveKeyFrameBackward( int position )
228 {
229  if ( position != 1 )
230  {
231  return swapKeyFrames( position, position - 1 );
232  }
233  else
234  {
235  return true;
236  }
237 }
238 
239 bool Layer::swapKeyFrames( int position1, int position2 ) //Current behaviour, need to refresh the swapped cels
240 {
241  bool keyPosition1 = false, keyPosition2 = false;
242  KeyFrame* pFirstFrame = nullptr;
243  KeyFrame* pSecondFrame = nullptr;
244 
245  if ( keyExists( position1 ) )
246  {
247  auto firstFrame = mKeyFrames.find( position1 );
248  pFirstFrame = firstFrame->second;
249 
250  mKeyFrames.erase( position1 );
251 
252  //pFirstFrame = getKeyFrameAt( position1 );
253  //removeKeyFrame( position1 );
254 
255  keyPosition1 = true;
256  }
257 
258  if ( keyExists( position2 ) )
259  {
260  auto secondFrame = mKeyFrames.find( position2 );
261  pSecondFrame = secondFrame->second;
262 
263  mKeyFrames.erase( position2 );
264 
265  //pSecondFrame = getKeyFrameAt( position2 );
266  //removeKeyFrame( position2 );
267 
268  keyPosition2 = true;
269  }
270 
271  if ( keyPosition2 )
272  {
273  //addKeyFrame( position1, pSecondFrame );
274  pSecondFrame->setPos( position1 );
275  mKeyFrames.insert( std::make_pair( position1, pSecondFrame ) );
276  }
277  else if ( position1 == 1 )
278  {
279  addNewEmptyKeyAt( position1 );
280  }
281 
282  if ( keyPosition1 )
283  {
284  //addKeyFrame( position2, pFirstFrame );
285  pFirstFrame->setPos( position2 );
286  mKeyFrames.insert( std::make_pair( position2, pFirstFrame ) );
287  }
288  else if ( position2 == 1 )
289  {
290  addNewEmptyKeyAt( position2 );
291  }
292 
293  return true;
294 }
295 
296 bool Layer::loadKey( KeyFrame* pKey )
297 {
298  auto it = mKeyFrames.find( pKey->pos() );
299  if ( it != mKeyFrames.end() )
300  {
301  delete it->second;
302  mKeyFrames.erase( it );
303  }
304  mKeyFrames.insert( std::make_pair( pKey->pos(), pKey ) );
305  return true;
306 }
307 
308 Status Layer::save( QString strDataFolder )
309 {
310  QStringList debugInfo = QStringList() << "Layer::save" << QString( "strDataFolder = " ).append( strDataFolder );
311  bool isOkay = true;
312  for ( auto pair : mKeyFrames )
313  {
314  KeyFrame* pKeyFrame = pair.second;
315  Status st = saveKeyFrame( pKeyFrame, strDataFolder );
316  if( !st.ok() )
317  {
318  isOkay = false;
319  QStringList keyFrameDetails = st.detailsList();
320  for ( QString detail : keyFrameDetails )
321  {
322  detail.prepend( "&nbsp;&nbsp;" );
323  }
324  debugInfo << QString( "- Keyframe[%1] failed to save" ).arg( pKeyFrame->pos() ) << keyFrameDetails;
325  }
326  }
327  if( !isOkay )
328  {
329  return Status( Status::FAIL, debugInfo );
330  }
331  return Status::OK;
332 }
333 
334 void Layer::paintTrack( QPainter& painter, TimeLineCells* cells, int x, int y, int width, int height, bool selected, int frameSize )
335 {
336  painter.setFont( QFont( "helvetica", height / 2 ) );
337  if ( mVisible )
338  {
339  QColor col;
340  if ( type() == BITMAP ) col = QColor( 151, 176, 244 );
341  if ( type() == VECTOR ) col = QColor( 150, 242, 150 );
342  if ( type() == SOUND ) col = QColor( 237, 147, 147 );
343  if ( type() == CAMERA ) col = QColor( 239, 232, 148 );
344 
345  painter.setBrush( col );
346  painter.setPen( QPen( QBrush( QColor( 100, 100, 100 ) ), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
347  painter.drawRect( x, y - 1, width, height );
348 
349  paintFrames( painter, cells, y, height, selected, frameSize );
350 
351  // changes the apparence if selected
352  if ( selected )
353  {
354  paintSelection( painter, x, y, width, height );
355  }
356  }
357  else
358  {
359  painter.setBrush( Qt::gray );
360  painter.setPen( QPen( QBrush( QColor( 100, 100, 100 ) ), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
361  painter.drawRect( x, y - 1, width, height ); // empty rectangle by default
362  }
363 }
364 
365 void Layer::paintFrames( QPainter& painter, TimeLineCells* cells, int y, int height, bool selected, int frameSize )
366 {
367  painter.setPen( QPen( QBrush( QColor( 40, 40, 40 ) ), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
368 
369  //qDebug() << "LayerType:" << ( int )( meType );
370 
371  for ( auto pair : mKeyFrames )
372  {
373  int framePos = pair.first;
374 
375  int recLeft = cells->getFrameX( framePos ) - frameSize + 2;
376  int recTop = y + 1;
377  int recWidth = frameSize - 2;
378  int recHeight = height - 4;
379 
380  KeyFrame* key = pair.second;
381  if ( key->length() > 1 )
382  {
383  // This is especially for sound clip.
384  // Sound clip is the only type of KeyFrame that has variant frame length.
385  recWidth = frameSize * key->length() - 2;
386  }
387 
388  if ( pair.second->isSelected() )
389  {
390  painter.setBrush( QColor( 60, 60, 60 ) );
391  }
392  else if ( selected )
393  {
394  painter.setBrush( QColor( 60, 60, 60, 120 ) );
395  }
396 
397  painter.drawRect( recLeft, recTop, recWidth, recHeight );
398  }
399 }
400 
401 void Layer::paintLabel( QPainter& painter, TimeLineCells* cells, int x, int y, int width, int height, bool selected, int allLayers )
402 {
403  Q_UNUSED( cells );
404  painter.setBrush( Qt::lightGray );
405  painter.setPen( QPen( QBrush( QColor( 100, 100, 100 ) ), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
406  painter.drawRect( x, y - 1, width, height ); // empty rectangle by default
407 
408  if ( mVisible )
409  {
410  if ( allLayers == 0 ) painter.setBrush( Qt::NoBrush );
411  if ( allLayers == 1 ) painter.setBrush( Qt::darkGray );
412  if ( ( allLayers == 2 ) || selected ) painter.setBrush( Qt::black );
413  }
414  else
415  {
416  painter.setBrush( Qt::NoBrush );
417  }
418  painter.setPen( Qt::black );
419  painter.setRenderHint( QPainter::Antialiasing, true );
420  painter.drawEllipse( x + 6, y + 4, 9, 9 );
421  painter.setRenderHint( QPainter::Antialiasing, false );
422 
423  if ( selected )
424  {
425  paintSelection( painter, x, y, width, height );
426  }
427 
428  if ( type() == BITMAP ) painter.drawPixmap( QPoint( 20, y + 2 ), QPixmap( ":/icons/layer-bitmap.png" ) );
429  if ( type() == VECTOR ) painter.drawPixmap( QPoint( 20, y + 2 ), QPixmap( ":/icons/layer-vector.png" ) );
430  if ( type() == SOUND ) painter.drawPixmap( QPoint( 21, y + 2 ), QPixmap( ":/icons/layer-sound.png" ) );
431  if ( type() == CAMERA ) painter.drawPixmap( QPoint( 21, y + 2 ), QPixmap( ":/icons/layer-camera.png" ) );
432 
433  painter.setFont( QFont( "helvetica", height / 2 ) );
434  painter.setPen( Qt::black );
435  painter.drawText( QPoint( 45, y + ( 2 * height ) / 3 ), mName );
436 }
437 
438 void Layer::paintSelection( QPainter& painter, int x, int y, int width, int height )
439 {
440  QLinearGradient linearGrad( QPointF( 0, y ), QPointF( 0, y + height ) );
441  QSettings settings( PENCIL2D, PENCIL2D );
442  QString style = settings.value( "style" ).toString();
443  linearGrad.setColorAt( 0, QColor( 255, 255, 255, 128 ) );
444  linearGrad.setColorAt( 0.50, QColor( 255, 255, 255, 64 ) );
445  linearGrad.setColorAt( 1, QColor( 255, 255, 255, 0 ) );
446  painter.setBrush( linearGrad );
447  painter.setPen( Qt::NoPen );
448  painter.drawRect( x, y, width, height - 1 );
449 }
450 
451 void Layer::mousePress( QMouseEvent* event, int frameNumber )
452 {
453  Q_UNUSED( event );
454  Q_UNUSED( frameNumber );
455 }
456 
457 void Layer::mouseDoubleClick( QMouseEvent* event, int frameNumber )
458 {
459  Q_UNUSED( event );
460  Q_UNUSED( frameNumber );
461 }
462 
463 void Layer::mouseMove( QMouseEvent* event, int frameNumber )
464 {
465  Q_UNUSED( event );
466  Q_UNUSED( frameNumber );
467 }
468 
469 void Layer::mouseRelease( QMouseEvent* event, int frameNumber )
470 {
471  Q_UNUSED( event );
472  Q_UNUSED( frameNumber );
473 }
474 
475 void Layer::editProperties()
476 {
477  QRegExp regex("([\\xFFEF-\\xFFFF])+");
478 
479  bool ok;
480  QString text = QInputDialog::getText( NULL, tr( "Layer Properties" ),
481  tr( "Layer name:" ), QLineEdit::Normal,
482  mName, &ok );
483  if ( ok && !text.isEmpty() )
484  {
485  text.replace(regex, "");
486  mName = text;
487  setUpdated();
488  }
489 }
490 
491 void Layer::setUpdated()
492 {
493  mObject->setLayerUpdated(mId);
494 }
495 
496 void Layer::setModified( int position, bool )
497 {
498  auto it = mKeyFrames.find( position );
499  if ( it != mKeyFrames.end() )
500  {
501  //KeyFrame* pKeyFrame = it->second;
502  //pKeyFrame->
503  }
504 }
505 
506 bool Layer::isFrameSelected(int position)
507 {
508  KeyFrame *keyFrame = getKeyFrameWhichCovers(position);
509  if(keyFrame)
510  {
511  return mSelectedFrames_byLast.contains(keyFrame->pos());
512  }
513  else
514  {
515  return false;
516  }
517 }
518 
519 void Layer::setFrameSelected(int position, bool isSelected)
520 {
521  KeyFrame *keyFrame = getKeyFrameWhichCovers(position);
522  if (keyFrame != nullptr) {
523  int startPosition = keyFrame->pos();
524 
525  if (isSelected && !mSelectedFrames_byLast.contains(startPosition)) {
526 
527  // Add the selected frame to the lists
528  //
529  mSelectedFrames_byLast.insert(0, startPosition);
530  mSelectedFrames_byPosition.append(startPosition);
531 
532  // We need to keep the list of selected frames sorted
533  // in order to easily handle their movement
534  //
535  qSort(mSelectedFrames_byPosition.begin(), mSelectedFrames_byPosition.end(), sortAsc);
536 
537  }
538  else if (!isSelected){
539 
540  // Remove the selected frame from the lists
541  //
542  int iLast = mSelectedFrames_byLast.indexOf(startPosition);
543  mSelectedFrames_byLast.removeAt(iLast);
544 
545  int iPos = mSelectedFrames_byPosition.indexOf(startPosition);
546  mSelectedFrames_byPosition.removeAt(iPos);
547  }
548  keyFrame->setSelected(isSelected);
549  }
550 }
551 
552 void Layer::toggleFrameSelected(int position, bool allowMultiple)
553 {
554  bool wasSelected = isFrameSelected(position);
555 
556  if (!allowMultiple) {
557  deselectAll();
558  }
559 
560  setFrameSelected(position, !wasSelected);
561 }
562 
563 void Layer::extendSelectionTo(int position)
564 {
565  if (mSelectedFrames_byLast.count() > 0 ) {
566  int lastSelected = mSelectedFrames_byLast[0];
567  int startPos;
568  int endPos;
569 
570  if (lastSelected < position) {
571  startPos = lastSelected;
572  endPos = position;
573  }
574  else {
575  startPos = position;
576  endPos = lastSelected;
577  }
578 
579  int i = startPos;
580  while (i <= endPos) {
581  setFrameSelected(i, true);
582  i++;
583  }
584  }
585 }
586 
587 void Layer::selectAllFramesAfter( int position )
588 {
589  int startPosition = position;
590  int endPosition = getMaxKeyFramePosition();
591 
592  if (!keyExists(startPosition)) {
593  startPosition = getNextKeyFramePosition(startPosition);
594  }
595 
596  if (startPosition > 0 && startPosition <= endPosition ) {
597  deselectAll();
598  setFrameSelected(startPosition, true);
599  extendSelectionTo(endPosition);
600  }
601 }
602 
603 void Layer::deselectAll()
604 {
605  mSelectedFrames_byLast.clear();
606  mSelectedFrames_byPosition.clear();
607 
608  for ( auto pair : mKeyFrames )
609  {
610  pair.second->setSelected(false);
611  }
612 }
613 
614 bool Layer::moveSelectedFrames(int offset)
615 {
616 
617  if (offset != 0 && mSelectedFrames_byPosition.count() > 0) {
618 
619  // If we are moving to the right we start moving selected frames from the highest (right) to the lowest (left)
620  int indexInSelection = mSelectedFrames_byPosition.count() - 1;
621  int step = -1;
622 
623  if (offset < 0) {
624 
625  // If we are moving to the left we start moving selected frames from the lowest (left) to the highest (right)
626  indexInSelection = 0;
627  step = 1;
628 
629  // Check if we are not moving out of the timeline
630  if (mSelectedFrames_byPosition[0] + offset < 1) {
631  return false;
632  }
633  }
634 
635 
636  while ( indexInSelection > -1 && indexInSelection < mSelectedFrames_byPosition.count() ) {
637 
638  int fromPos = mSelectedFrames_byPosition[indexInSelection];
639  int toPos = fromPos + offset;
640 
641  // Get the frame to move
642  KeyFrame *selectedFrame = getKeyFrameAt(fromPos);
643 
644  if (selectedFrame != nullptr) {
645 
646  mKeyFrames.erase(fromPos);
647 
648  // Slide back every frame between fromPos to toPos
649  // to avoid having 2 frames in the same position
650  //
651  bool isBetween = true;
652  int targetPosition = fromPos;
653 
654  while (isBetween) {
655 
656  int framePosition = targetPosition - step;
657 
658  KeyFrame *frame = getKeyFrameAt(framePosition);
659 
660  if (frame != nullptr) {
661  mKeyFrames.erase(framePosition);
662 
663  frame->setPos(targetPosition);
664  mKeyFrames.insert( std::make_pair( targetPosition, frame ) );
665  }
666 
667  targetPosition = targetPosition - step;
668  if (fromPos < toPos && (targetPosition < fromPos || targetPosition >= toPos)) {
669  isBetween = false;
670  }
671  if (fromPos > toPos && (targetPosition > fromPos || targetPosition <= toPos)) {
672  isBetween = false;
673  }
674  }
675 
676  // If the first frame is moving, we need to create a new first frame
677  if (fromPos == 1) {
678  addNewEmptyKeyAt(1);
679  }
680 
681  // Update the position of the selected frame
682  selectedFrame->setPos(toPos);
683  mKeyFrames.insert( std::make_pair( toPos, selectedFrame ) );
684  }
685 
686  indexInSelection = indexInSelection + step;
687  }
688 
689 
690  // Update selection lists
691  //
692  for (int i=0; i<mSelectedFrames_byPosition.count(); i++) {
693  mSelectedFrames_byPosition[i] = mSelectedFrames_byPosition[i] + offset;
694  }
695  for (int i=0; i<mSelectedFrames_byLast.count(); i++) {
696  mSelectedFrames_byLast[i] = mSelectedFrames_byLast[i] + offset;
697  }
698 
699  return true;
700  }
701  else {
702  return false;
703  }
704 
705 }
706 
707 bool isLayerPaintable( Layer* layer )
708 {
709  Q_ASSERT( layer != nullptr );
710 
711  switch ( layer->type() )
712  {
713  case Layer::BITMAP:
714  case Layer::VECTOR:
715  return true;
716  default:
717  break;
718  }
719  return false;
720 }
721 
722 bool Layer::keyExistsWhichCovers(int frameNumber)
723 {
724  return getKeyFrameWhichCovers(frameNumber) != nullptr;
725 }
726 
727 KeyFrame *Layer::getKeyFrameWhichCovers(int frameNumber)
728 {
729  auto keyFrame = getLastKeyFrameAtPosition(frameNumber);
730 
731  if( keyFrame != nullptr )
732  {
733  if(keyFrame->pos() + keyFrame->length() > frameNumber)
734  {
735  return keyFrame;
736  }
737  }
738 
739  return nullptr;
740 }
Definition: layer.h:32
Definition: object.h:71