20 #include <QApplication>
23 #include <QImageReader>
26 #include <QTemporaryDir>
29 #include "vectorimage.h"
30 #include "bitmapimage.h"
31 #include "soundclip.h"
32 #include "layerbitmap.h"
33 #include "layervector.h"
34 #include "layercamera.h"
35 #include "backupelement.h"
37 #include "colormanager.h"
38 #include "toolmanager.h"
39 #include "layermanager.h"
40 #include "playbackmanager.h"
41 #include "viewmanager.h"
42 #include "preferencemanager.h"
43 #include "soundmanager.h"
44 #include "selectionmanager.h"
46 #include "scribblearea.h"
58 clipboardBitmapOk =
false;
59 clipboardVectorOk =
false;
60 clipboardSoundClipOk =
false;
102 mIsAutosave = mPreferenceManager->isOn(SETTING::AUTO_SAVE);
103 mAutosaveNumber = mPreferenceManager->getInt(SETTING::AUTO_SAVE_NUMBER);
108 int Editor::currentFrame()
115 return mPlaybackManager->fps();
118 void Editor::setFps(
int fps)
120 mPreferenceManager->set(SETTING::FPS, fps);
121 emit fpsChanged(fps);
124 void Editor::makeConnections()
126 connect(mPreferenceManager, &PreferenceManager::optionChanged,
this, &Editor::settingUpdated);
134 event->acceptProposedAction();
141 for (
int i = 0; i <
event->mimeData()->urls().size(); i++)
143 if (i > 0) scrubForward();
144 QUrl url =
event->mimeData()->urls()[i];
148 importImage(filePath);
156 void Editor::settingUpdated(SETTING setting)
160 case SETTING::AUTO_SAVE:
161 mIsAutosave = mPreferenceManager->isOn(SETTING::AUTO_SAVE);
163 case SETTING::AUTO_SAVE_NUMBER:
164 mAutosaveNumber = mPreferenceManager->getInt(SETTING::AUTO_SAVE_NUMBER);
166 case SETTING::ONION_TYPE:
167 mScribbleArea->updateAllFrames();
168 emit updateTimeLine();
170 case SETTING::FRAME_POOL_SIZE:
171 mObject->setActiveFramePoolSize(mPreferenceManager->getInt(SETTING::FRAME_POOL_SIZE));
173 case SETTING::LAYER_VISIBILITY:
174 mScribbleArea->setLayerVisibility(static_cast<LayerVisibility>(mPreferenceManager->getInt(SETTING::LAYER_VISIBILITY)));
175 emit updateTimeLine();
184 if (mBackupIndex >= 0)
186 return mBackupList[mBackupIndex];
194 void Editor::backup(
QString undoText)
197 if (mLastModifiedLayer > -1 && mLastModifiedFrame > 0)
199 if (layers()->currentLayer()->type() == Layer::SOUND)
201 frame = layers()->currentLayer()->getKeyFrameWhichCovers(mLastModifiedFrame);
202 if (frame !=
nullptr)
204 backup(mLastModifiedLayer, frame->pos(), undoText);
209 backup(mLastModifiedLayer, mLastModifiedFrame, undoText);
212 if (mLastModifiedLayer != layers()->currentLayerIndex() || mLastModifiedFrame != currentFrame())
214 if (layers()->currentLayer()->type() == Layer::SOUND)
216 frame = layers()->currentLayer()->getKeyFrameWhichCovers(currentFrame());
218 if (frame !=
nullptr)
220 backup(layers()->currentLayerIndex(), frame->pos(), undoText);
225 backup(layers()->currentLayerIndex(), currentFrame(), undoText);
230 void Editor::backup(
int backupLayer,
int backupFrame,
QString undoText)
232 while (mBackupList.
size() - 1 > mBackupIndex && mBackupList.
size() > 0)
236 while (mBackupList.
size() > 19)
242 Layer* layer = mObject->getLayer(backupLayer);
243 if (layer !=
nullptr)
245 if (layer->type() == Layer::BITMAP)
248 if (currentFrame() == 1) {
249 int previous = layer->getPreviousKeyFramePosition(backupFrame);
250 bitmapImage =
static_cast<LayerBitmap*
>(layer)->getBitmapImageAtFrame(previous);
252 if (bitmapImage !=
nullptr)
255 element->layer = backupLayer;
256 element->frame = bitmapImage->pos();
257 element->undoText = undoText;
258 element->somethingSelected = select()->somethingSelected();
259 element->mySelection = select()->mySelectionRect();
260 element->myTransformedSelection = select()->myTransformedSelectionRect();
261 element->myTempTransformedSelection = select()->myTempTransformedSelectionRect();
262 element->rotationAngle = select()->myRotation();
263 mBackupList.
append(element);
267 else if (layer->type() == Layer::VECTOR)
270 if (vectorImage !=
nullptr)
273 element->layer = backupLayer;
274 element->frame = vectorImage->pos();
275 element->undoText = undoText;
276 element->somethingSelected = select()->somethingSelected();
277 element->mySelection = select()->mySelectionRect();
278 element->myTransformedSelection = select()->myTransformedSelectionRect();
279 element->myTempTransformedSelection = select()->myTempTransformedSelectionRect();
280 element->rotationAngle = select()->myRotation();
281 mBackupList.
append(element);
285 else if (layer->type() == Layer::SOUND)
287 int previous = layer->getPreviousKeyFramePosition(backupFrame);
288 KeyFrame* key = layer->getLastKeyFrameAtPosition(backupFrame);
293 KeyFrame* previousKey = layer->getKeyFrameAt(previous);
296 if (key !=
nullptr) {
301 element->layer = backupLayer;
302 element->frame = backupFrame;
303 element->undoText = undoText;
304 element->fileName = clip->fileName();
305 mBackupList.
append(element);
312 updateAutoSaveCounter();
319 for (
int i = 0; i < mBackupList.
size(); i++)
325 switch (backupElement->type())
327 case BackupElement::BITMAP_MODIF:
329 Q_ASSERT(bitmapElement);
330 if (bitmapElement->layer > layerIndex)
332 bitmapElement->layer--;
335 else if (bitmapElement->layer != layerIndex)
340 case BackupElement::VECTOR_MODIF:
342 Q_ASSERT(vectorElement);
343 if (vectorElement->layer > layerIndex)
345 vectorElement->layer--;
348 else if (vectorElement->layer != layerIndex)
353 case BackupElement::SOUND_MODIF:
355 Q_ASSERT(soundElement);
356 if (soundElement->layer > layerIndex)
358 soundElement->layer--;
361 else if (soundElement->layer != layerIndex)
369 if (i <= mBackupIndex) {
377 void Editor::restoreKey()
379 BackupElement* lastBackupElement = mBackupList[mBackupIndex];
381 Layer* layer =
nullptr;
384 if (lastBackupElement->type() == BackupElement::BITMAP_MODIF)
387 layerIndex = lastBackupBitmapElement->layer;
388 frame = lastBackupBitmapElement->frame;
389 layer = object()->getLayer(layerIndex);
390 addKeyFrame(layerIndex, frame);
391 dynamic_cast<LayerBitmap*
>(layer)->getBitmapImageAtFrame(frame)->paste(&lastBackupBitmapElement->bitmapImage);
393 if (lastBackupElement->type() == BackupElement::VECTOR_MODIF)
396 layerIndex = lastBackupVectorElement->layer;
397 frame = lastBackupVectorElement->frame;
398 layer = object()->getLayer(layerIndex);
399 addKeyFrame(layerIndex, frame);
400 dynamic_cast<LayerVector*
>(layer)->getVectorImageAtFrame(frame)->paste(lastBackupVectorElement->vectorImage);
402 if (lastBackupElement->type() == BackupElement::SOUND_MODIF)
406 layerIndex = lastBackupSoundElement->layer;
407 frame = lastBackupSoundElement->frame;
409 strSoundFile = lastBackupSoundElement->fileName;
410 KeyFrame* key = addKeyFrame(layerIndex, frame);
429 if (mBackupList.
size() > 0 && mBackupIndex > -1)
431 if (mBackupIndex == mBackupList.
size() - 1)
433 BackupElement* lastBackupElement = mBackupList[mBackupIndex];
434 if (lastBackupElement->type() == BackupElement::BITMAP_MODIF)
437 backup(lastBackupBitmapElement->layer, lastBackupBitmapElement->frame,
"NoOp");
440 if (lastBackupElement->type() == BackupElement::VECTOR_MODIF)
443 backup(lastBackupVectorElement->layer, lastBackupVectorElement->frame,
"NoOp");
446 if (lastBackupElement->type() == BackupElement::SOUND_MODIF)
449 backup(lastBackupSoundElement->layer, lastBackupSoundElement->frame,
"NoOp");
454 mBackupList[mBackupIndex]->restore(
this);
456 mScribbleArea->cancelTransformedSelection();
458 Layer* layer = layers()->currentLayer();
459 if (layer ==
nullptr) {
return; }
461 select()->resetSelectionTransform();
462 if (layer->type() == Layer::VECTOR) {
465 select()->setSelection(vectorImage->getSelectionRect(),
false);
473 if (mBackupList.
size() > 0 && mBackupIndex < mBackupList.
size() - 2)
477 mBackupList[mBackupIndex + 1]->restore(
this);
482 void Editor::clearUndoStack()
489 mLastModifiedLayer = -1;
490 mLastModifiedFrame = -1;
493 void Editor::updateAutoSaveCounter()
495 if (mIsAutosave ==
false)
499 if (mAutosaveCounter >= mAutosaveNumber)
501 resetAutoSaveCounter();
506 void Editor::resetAutoSaveCounter()
508 mAutosaveCounter = 0;
514 mScribbleArea->deleteSelection();
520 Layer* layer = mObject->getLayer(layers()->currentLayerIndex());
521 if (layer ==
nullptr)
526 if (layer->type() == Layer::BITMAP)
529 BitmapImage* bitmapImage = layerBitmap->getLastBitmapImageAtFrame(currentFrame(), 0);
530 if (bitmapImage ==
nullptr) {
return; }
531 if (select()->somethingSelected())
533 g_clipboardBitmapImage = bitmapImage->copy(select()->mySelectionRect().toRect());
537 g_clipboardBitmapImage = bitmapImage->copy();
539 clipboardBitmapOk =
true;
540 if (g_clipboardBitmapImage.image() !=
nullptr)
543 if (layer->type() == Layer::VECTOR)
545 clipboardVectorOk =
true;
546 VectorImage *vectorImage =
static_cast<LayerVector*
>(layer)->getLastVectorImageAtFrame(currentFrame(), 0);
547 if (vectorImage ==
nullptr) {
return; }
548 g_clipboardVectorImage = *vectorImage;
554 Layer* layer = mObject->getLayer(layers()->currentLayerIndex());
555 if (layer !=
nullptr)
557 if (layer->type() == Layer::BITMAP && g_clipboardBitmapImage.image() !=
nullptr)
561 BitmapImage tobePasted = g_clipboardBitmapImage.copy();
562 qDebug() <<
"to be pasted --->" << tobePasted.image()->
size();
563 if (select()->somethingSelected())
565 QRectF selection = select()->mySelectionRect();
566 if (g_clipboardBitmapImage.width() <= selection.
width() && g_clipboardBitmapImage.height() <= selection.
height())
568 tobePasted.moveTopLeft(selection.
topLeft());
572 tobePasted.transform(selection,
true);
575 auto pLayerBitmap =
static_cast<LayerBitmap*
>(layer);
577 BitmapImage *bitmapImage = pLayerBitmap->getLastBitmapImageAtFrame(currentFrame(), 0);
578 Q_CHECK_PTR(bitmapImage);
579 bitmapImage->paste(&tobePasted);
581 else if (layer->type() == Layer::VECTOR && clipboardVectorOk)
586 VectorImage* vectorImage =
static_cast<LayerVector*
>(layer)->getLastVectorImageAtFrame(currentFrame(), 0);
587 Q_CHECK_PTR(vectorImage);
588 vectorImage->
paste(g_clipboardVectorImage);
589 select()->setSelection(vectorImage->getSelectionRect(),
false);
592 mScribbleArea->updateCurrentFrame();
595 void Editor::flipSelection(
bool flipVertical)
597 mScribbleArea->flipSelection(flipVertical);
600 void Editor::clipboardChanged()
602 if (clipboardBitmapOk ==
false)
605 g_clipboardBitmapImage.bounds() =
QRect(g_clipboardBitmapImage.topLeft(), g_clipboardBitmapImage.image()->
size());
610 clipboardBitmapOk =
false;
616 mScribbleArea->setLayerVisibility(visibility);
617 emit updateTimeLine();
620 void Editor::notifyAnimationLengthChanged()
622 layers()->notifyAnimationLengthChanged();
625 LayerVisibility Editor::layerVisibility()
627 return mScribbleArea->getLayerVisibility();
630 void Editor::increaseLayerVisibilityIndex()
632 mScribbleArea->increaseLayerVisibilityIndex();
633 emit updateTimeLine();
636 void Editor::decreaseLayerVisibilityIndex()
638 mScribbleArea->decreaseLayerVisibilityIndex();
639 emit updateTimeLine();
642 void Editor::toggleOnionSkinType()
644 QString onionSkinState = mPreferenceManager->getString(SETTING::ONION_TYPE);
646 if (onionSkinState ==
"relative")
648 newState =
"absolute";
652 newState =
"relative";
655 mPreferenceManager->set(SETTING::ONION_TYPE, newState);
660 mTemporaryDirs.
append(dir);
663 void Editor::clearTemporary()
665 while(!mTemporaryDirs.
isEmpty()) {
672 if (newObject ==
nullptr)
675 return Status::INVALID_ARGUMENT;
678 if (newObject == mObject.get())
684 mObject.reset(newObject);
686 g_clipboardVectorImage.setObject(newObject);
693 m->load(mObject.get());
698 connect(newObject, &Object::layerViewChanged, mViewManager, &ViewManager::viewChanged);
706 void Editor::updateObject()
708 setCurrentLayerIndex(mObject->data()->getCurrentLayer());
709 scrubTo(mObject->data()->getCurrentFrame());
711 mAutosaveCounter = 0;
712 mAutosaveNeverAskAgain =
false;
716 mScribbleArea->updateAllFrames();
719 if (mPreferenceManager)
721 mObject->setActiveFramePoolSize(mPreferenceManager->getInt(SETTING::FRAME_POOL_SIZE));
724 emit updateLayerCount();
727 bool Editor::importBitmapImage(
QString filePath,
int space)
731 Q_ASSERT(layers()->currentLayer()->type() == Layer::BITMAP);
732 auto layer =
static_cast<LayerBitmap*
>(layers()->currentLayer());
740 const QPoint pos =
QPoint(static_cast<int>(view()->getImportView().dx()),
741 static_cast<int>(view()->getImportView().dy())) -
QPoint(img.width() / 2, img.height() / 2);
742 while (reader.read(&img))
744 if (!layer->keyExists(currentFrame()))
748 BitmapImage* bitmapImage = layer->getBitmapImageAtFrame(currentFrame());
750 bitmapImage->paste(&importedBitmapImage);
753 scrubTo(currentFrame() + space);
755 scrubTo(currentFrame() + 1);
758 backup(
tr(
"Import Image"));
761 if (!reader.supportsAnimation())
770 bool Editor::importVectorImage(
QString filePath)
772 Q_ASSERT(layers()->currentLayer()->type() == Layer::VECTOR);
774 auto layer =
static_cast<LayerVector*
>(layers()->currentLayer());
777 if (vectorImage ==
nullptr)
780 vectorImage = (
static_cast<LayerVector*
>(layer))->getVectorImageAtFrame(currentFrame());
784 bool ok = importedVectorImage.
read(filePath);
788 vectorImage->
paste(importedVectorImage);
790 backup(
tr(
"Import Image"));
796 void Editor::createNewBitmapLayer(
const QString& name)
798 Layer* layer = layers()->createBitmapLayer(name);
799 layers()->setCurrentLayer(layer);
802 void Editor::createNewVectorLayer(
const QString& name)
804 Layer* layer = layers()->createVectorLayer(name);
805 layers()->setCurrentLayer(layer);
808 void Editor::createNewSoundLayer(
const QString& name)
810 Layer* layer = layers()->createVectorLayer(name);
811 layers()->setCurrentLayer(layer);
814 void Editor::createNewCameraLayer(
const QString& name)
816 Layer* layer = layers()->createCameraLayer(name);
817 layers()->setCurrentLayer(layer);
820 bool Editor::importImage(
QString filePath)
822 Layer* layer = layers()->currentLayer();
824 if (view()->getImportFollowsCamera())
827 QTransform transform = camera->getViewAtFrame(currentFrame());
828 view()->setImportView(transform);
830 switch (layer->type())
833 return importBitmapImage(filePath);
836 return importVectorImage(filePath);
846 bool Editor::importGIF(
QString filePath,
int numOfImages)
848 Layer* layer = layers()->currentLayer();
849 if (layer->type() == Layer::BITMAP)
851 return importBitmapImage(filePath, numOfImages);
856 qreal Editor::viewScaleInversed()
858 return view()->getViewInverse().
m11();
861 void Editor::selectAll()
863 Layer* layer = layers()->currentLayer();
866 if (layer->type() == Layer::BITMAP)
871 if (bitmapImage ==
nullptr) {
return; }
873 rect = bitmapImage->bounds();
875 else if (layer->type() == Layer::VECTOR)
878 if (vectorImage !=
nullptr)
881 rect = vectorImage->getSelectionRect();
884 select()->setSelection(rect,
false);
887 void Editor::deselectAll()
889 Layer* layer = layers()->currentLayer();
890 if (layer ==
nullptr) {
return; }
892 if (layer->type() == Layer::VECTOR)
895 if (vectorImage !=
nullptr)
901 select()->resetSelectionProperties();
904 void Editor::updateFrame(
int frameNumber)
906 mScribbleArea->updateFrame(frameNumber);
909 void Editor::updateFrameAndVector(
int frameNumber)
911 mScribbleArea->updateAllVectorLayersAt(frameNumber);
914 void Editor::updateCurrentFrame()
916 mScribbleArea->updateCurrentFrame();
919 void Editor::setCurrentLayerIndex(
int i)
921 mCurrentLayerIndex = i;
923 Layer* layer = mObject->getLayer(i);
924 for (
auto mgr : mAllManagers)
926 mgr->workingLayerChanged(layer);
930 void Editor::scrubTo(
int frame)
932 if (frame < 1) { frame = 1; }
933 int oldFrame = mFrame;
936 emit currentFrameChanged(oldFrame);
937 emit currentFrameChanged(frame);
942 if (mPlaybackManager && !mPlaybackManager->isPlaying())
944 emit updateTimeLine();
946 mObject->updateActiveFrames(frame);
949 void Editor::scrubForward()
951 int nextFrame = mFrame + 1;
952 if (!playback()->isPlaying()) {
953 playback()->playScrub(nextFrame);
958 void Editor::scrubBackward()
960 if (currentFrame() > 1)
962 int previousFrame = mFrame - 1;
963 if (!playback()->isPlaying()) {
964 playback()->playScrub(previousFrame);
966 scrubTo(previousFrame);
972 return addKeyFrame(layers()->currentLayerIndex(), currentFrame());
975 KeyFrame* Editor::addKeyFrame(
int layerNumber,
int frameIndex)
977 Layer* layer = mObject->getLayer(layerNumber);
978 if (layer ==
nullptr)
984 if (!layer->visible())
986 mScribbleArea->showLayerNotVisibleWarning();
991 while (layer->keyExists(frameIndex))
993 if (layer->type() == Layer::SOUND &&
static_cast<SoundClip*
>(layer->getKeyFrameAt(frameIndex))->fileName().isEmpty()
994 && layer->removeKeyFrame(frameIndex))
1004 bool ok = layer->addNewKeyFrameAt(frameIndex);
1007 scrubTo(frameIndex);
1008 layers()->notifyAnimationLengthChanged();
1010 return layer->getKeyFrameAt(frameIndex);
1013 void Editor::removeKey()
1015 Layer* layer = layers()->currentLayer();
1016 Q_ASSERT(layer !=
nullptr);
1018 if (!layer->visible())
1020 mScribbleArea->showLayerNotVisibleWarning();
1024 if (!layer->keyExistsWhichCovers(currentFrame()))
1029 backup(
tr(
"Remove frame"));
1032 layer->removeKeyFrame(currentFrame());
1035 layers()->notifyAnimationLengthChanged();
1036 emit layers()->currentLayerChanged(layers()->currentLayerIndex());
1039 void Editor::scrubNextKeyFrame()
1041 Layer* layer = layers()->currentLayer();
1044 int nextPosition = layer->getNextKeyFramePosition(currentFrame());
1045 scrubTo(nextPosition);
1048 void Editor::scrubPreviousKeyFrame()
1050 Layer* layer = mObject->getLayer(layers()->currentLayerIndex());
1053 int prevPosition = layer->getPreviousKeyFramePosition(currentFrame());
1054 scrubTo(prevPosition);
1057 void Editor::switchVisibilityOfLayer(
int layerNumber)
1059 Layer* layer = mObject->getLayer(layerNumber);
1060 if (layer !=
nullptr) layer->switchVisibility();
1061 mScribbleArea->updateAllFrames();
1063 emit updateTimeLine();
1066 void Editor::swapLayers(
int i,
int j)
1068 mObject->swapLayers(i, j);
1071 layers()->setCurrentLayer(j + 1);
1075 layers()->setCurrentLayer(j - 1);
1077 emit updateTimeLine();
1078 mScribbleArea->updateAllFrames();
1087 BitmapImage* img = layerbitmap->getBitmapImageAtFrame(currentFrame());
1088 QRectF rect = select()->mySelectionRect();
1089 retLeft = img->findLeft(rect, 121);
1090 retRight = img->findTop(rect, 121);
1091 if (STATUS_FAILED(retLeft.errorcode) || STATUS_FAILED(retRight.errorcode))
1093 return Status(Status::FAIL,
"",
tr(
"Peg hole not found!\nCheck selection, and please try again.",
"PegBar error message"));
1095 const int peg_x = retLeft.value;
1096 const int peg_y = retRight.value;
1099 for (
int i = 0; i < layers.
count(); i++)
1101 layerbitmap =
static_cast<LayerBitmap*
>(mLayerManager->findLayerByName(layers.
at(i)));
1102 for (
int k = layerbitmap->firstKeyFramePosition(); k <= layerbitmap->getMaxKeyFramePosition(); k++)
1104 if (layerbitmap->keyExists(k))
1106 img = layerbitmap->getBitmapImageAtFrame(k);
1107 retLeft = img->findLeft(rect, 121);
1108 const QString errorDescription =
tr(
"Peg bar not found at %1, %2").
arg(layerbitmap->name()).arg(k);
1109 if (STATUS_FAILED(retLeft.errorcode))
1111 return Status(retLeft.errorcode,
"", errorDescription);
1113 retRight = img->findTop(rect, 121);
1114 if (STATUS_FAILED(retRight.errorcode))
1116 return Status(retRight.errorcode,
"", errorDescription);
1118 img->moveTopLeft(
QPoint(img->left() + (peg_x - retLeft.value), img->top() + (peg_y - retRight.value)));
1124 return retLeft.errorcode;
1127 void Editor::prepareSave()
1129 for (
auto mgr : mAllManagers)
1131 mgr->save(mObject.get());
1135 void Editor::clearCurrentFrame()
1137 mScribbleArea->clearImage();
const QMimeData * mimeData() const const
void setLayerVisibility(LayerVisibility visibility)
The visiblity value should match any of the VISIBILITY enum values.
void calculateSelectionRect()
VectorImage::calculateSelectionRect.
bool read(QString filePath)
VectorImage::read.
const T & at(int i) const const
void deselectAll()
VectorImage::deselectAll.
QString tr(const char *sourceText, const char *disambiguation, int n)
int count(const T &value) const const
void append(const T &value)
void selectAll()
VectorImage::selectAll.
void handleDrawingOnEmptyFrame()
Call this when starting to use a paint tool.
bool isEmpty() const const
QPointF topLeft() const const
bool isEmpty() const const
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const const
QString toLocalFile() const const
void setImage(const QImage &image, QClipboard::Mode mode)
qreal width() const const
bool hasUrls() const const
void paste(VectorImage &)
VectorImage::paste.
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
qreal height() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
T qobject_cast(QObject *object)
void sanitizeBackupElementsAfterLayerDeletion(int layerIndex)
Restores integrity of the backup elements after a layer has been deleted.