void DocumentApi::moveFrameBefore(Sprite* sprite, FrameNumber frame, FrameNumber beforeFrame) { if (frame != beforeFrame && frame >= 0 && frame <= sprite->getLastFrame() && beforeFrame >= 0 && beforeFrame <= sprite->getLastFrame()) { // Change the frame-lengths... int frlen_aux = sprite->getFrameDuration(frame); // Moving the frame to the future. if (frame < beforeFrame) { for (FrameNumber c=frame; c<beforeFrame.previous(); ++c) setFrameDuration(sprite, c, sprite->getFrameDuration(c.next())); setFrameDuration(sprite, beforeFrame.previous(), frlen_aux); } // Moving the frame to the past. else if (beforeFrame < frame) { for (FrameNumber c=frame; c>beforeFrame; --c) setFrameDuration(sprite, c, sprite->getFrameDuration(c.previous())); setFrameDuration(sprite, beforeFrame, frlen_aux); } // change the cels of position... moveFrameBeforeLayer(sprite->getFolder(), frame, beforeFrame); } }
void ClearCelCommand::onExecute(Context* context) { ContextWriter writer(context); Document* document(writer.document()); { UndoTransaction undoTransaction(writer.context(), "Clear Cel"); // TODO the range of selected frames should be in the DocumentLocation. Timeline::Range range = App::instance()->getMainWindow()->getTimeline()->range(); if (range.enabled()) { Sprite* sprite = writer.sprite(); for (LayerIndex layerIdx = range.layerBegin(); layerIdx <= range.layerEnd(); ++layerIdx) { Layer* layer = sprite->indexToLayer(layerIdx); if (!layer->isImage()) continue; LayerImage* layerImage = static_cast<LayerImage*>(layer); for (FrameNumber frame = range.frameEnd(), begin = range.frameBegin().previous(); frame != begin; frame = frame.previous()) { document->getApi().clearCel(layerImage, frame); } } } else { document->getApi().clearCel(writer.cel()); } undoTransaction.commit(); } update_screen_for_document(document); }
void DocumentApi::copyPreviousFrame(Layer* layer, FrameNumber frame) { ASSERT(layer); ASSERT(frame >= 0); Sprite* sprite = layer->getSprite(); // create a copy of the previous cel Cel* src_cel = static_cast<LayerImage*>(layer)->getCel(frame.previous()); Image* src_image = src_cel ? sprite->getStock()->getImage(src_cel->getImage()): NULL; // nothing to copy, it will be a transparent cel if (!src_image) return; // copy the image Image* dst_image = Image::createCopy(src_image); int image_index = addImageInStock(sprite, dst_image); // create the new cel Cel* dst_cel = new Cel(frame, image_index); if (src_cel) { // copy the data from the previous cel dst_cel->setPosition(src_cel->getX(), src_cel->getY()); dst_cel->setOpacity(src_cel->getOpacity()); } // add the cel in the layer addCel(static_cast<LayerImage*>(layer), dst_cel); }
FrameNumber onGetFrame(Editor* editor) override { FrameNumber frame = editor->frame(); if (frame > FrameNumber(0)) return frame.previous(); else return editor->sprite()->lastFrame(); }
raster::FrameNumber calculate_next_frame( raster::Sprite* sprite, raster::FrameNumber frame, IDocumentSettings* docSettings, bool& pingPongForward) { FrameNumber first = FrameNumber(0); FrameNumber last = sprite->getLastFrame(); if (docSettings->getLoopAnimation()) { FrameNumber loopBegin, loopEnd; docSettings->getLoopRange(&loopBegin, &loopEnd); if (loopBegin < first) loopBegin = first; if (loopEnd > last) loopEnd = last; first = loopBegin; last = loopEnd; } switch (docSettings->getAnimationDirection()) { case IDocumentSettings::AniDir_Normal: frame = frame.next(); if (frame > last) frame = first; break; case IDocumentSettings::AniDir_Reverse: frame = frame.previous(); if (frame < first) frame = last; break; case IDocumentSettings::AniDir_PingPong: if (pingPongForward) { frame = frame.next(); if (frame > last) { frame = last.previous(); if (frame < first) frame = first; pingPongForward = false; } } else { frame = frame.previous(); if (frame < first) { frame = first.next(); if (frame > last) frame = last; pingPongForward = true; } } break; } return frame; }
void DocumentApi::moveFrameBeforeLayer(Layer* layer, FrameNumber frame, FrameNumber beforeFrame) { ASSERT(layer); switch (layer->getType()) { case GFXOBJ_LAYER_IMAGE: { CelIterator it = ((LayerImage*)layer)->getCelBegin(); CelIterator end = ((LayerImage*)layer)->getCelEnd(); for (; it != end; ++it) { Cel* cel = *it; FrameNumber newFrame = cel->getFrame(); // moving the frame to the future if (frame < beforeFrame) { if (cel->getFrame() == frame) { newFrame = beforeFrame.previous(); } else if (cel->getFrame() > frame && cel->getFrame() < beforeFrame) { --newFrame; } } // moving the frame to the past else if (beforeFrame < frame) { if (cel->getFrame() == frame) { newFrame = beforeFrame; } else if (cel->getFrame() >= beforeFrame && cel->getFrame() < frame) { ++newFrame; } } if (cel->getFrame() != newFrame) setCelFramePosition(layer->getSprite(), cel, newFrame); } break; } case GFXOBJ_LAYER_FOLDER: { LayerIterator it = static_cast<LayerFolder*>(layer)->getLayerBegin(); LayerIterator end = static_cast<LayerFolder*>(layer)->getLayerEnd(); for (; it != end; ++it) moveFrameBeforeLayer(*it, frame, beforeFrame); break; } } }
// TODO the DocumentRange should be "iteratable" to replace this function CelList get_cels_in_range(Sprite* sprite, const DocumentRange& range) { CelList cels; for (LayerIndex layerIdx = range.layerBegin(); layerIdx <= range.layerEnd(); ++layerIdx) { Layer* layer = sprite->indexToLayer(layerIdx); if (!layer->isImage()) continue; LayerImage* layerImage = static_cast<LayerImage*>(layer); for (FrameNumber frame = range.frameEnd(), begin = range.frameBegin().previous(); frame != begin; frame = frame.previous()) { Cel* cel = layerImage->getCel(frame); if (cel) cels.push_back(cel); } } return cels; }