Example #1
0
void move_cel(ContextWriter& writer)
{
  Document* document = writer.document();
  Sprite* sprite = writer.sprite();
  Cel *src_cel, *dst_cel;

  ASSERT(src_layer != NULL);
  ASSERT(dst_layer != NULL);
  ASSERT(src_frame >= 0 && src_frame < sprite->getTotalFrames());
  ASSERT(dst_frame >= 0 && dst_frame < sprite->getTotalFrames());

  if (src_layer->isBackground()) {
    copy_cel(writer);
    return;
  }

  src_cel = static_cast<LayerImage*>(src_layer)->getCel(src_frame);
  dst_cel = static_cast<LayerImage*>(dst_layer)->getCel(dst_frame);

  UndoTransaction undo(writer.context(), "Move Cel", undo::ModifyDocument);

  /* remove the 'dst_cel' (if it exists) because it must be
     replaced with 'src_cel' */
  if ((dst_cel != NULL) && (!dst_layer->isBackground() || src_cel != NULL))
    remove_cel(sprite, undo, static_cast<LayerImage*>(dst_layer), dst_cel);

  /* move the cel in the same layer */
  if (src_cel != NULL) {
    if (src_layer == dst_layer) {
      if (undo.isEnabled())
        undo.pushUndoer(new undoers::SetCelFrame(undo.getObjects(), src_cel));

      src_cel->setFrame(dst_frame);
    }
    /* move the cel in different layers */
    else {
      if (undo.isEnabled())
        undo.pushUndoer(new undoers::RemoveCel(undo.getObjects(), src_layer, src_cel));
      static_cast<LayerImage*>(src_layer)->removeCel(src_cel);

      src_cel->setFrame(dst_frame);

      /* if we are moving a cel from a transparent layer to the
         background layer, we have to clear the background of the
         image */
      if (!src_layer->isBackground() &&
          dst_layer->isBackground()) {
        Image *src_image = sprite->getStock()->getImage(src_cel->getImage());
        Image *dst_image = image_crop(src_image,
                                      -src_cel->getX(),
                                      -src_cel->getY(),
                                      sprite->getWidth(),
                                      sprite->getHeight(), 0);

        if (undo.isEnabled()) {
          undo.pushUndoer(new undoers::ReplaceImage(undo.getObjects(),
              sprite->getStock(), src_cel->getImage()));
          undo.pushUndoer(new undoers::SetCelPosition(undo.getObjects(), src_cel));
          undo.pushUndoer(new undoers::SetCelOpacity(undo.getObjects(), src_cel));
        }

        image_clear(dst_image, app_get_color_to_clear_layer(dst_layer));
        image_merge(dst_image, src_image, src_cel->getX(), src_cel->getY(), 255, BLEND_MODE_NORMAL);

        src_cel->setPosition(0, 0);
        src_cel->setOpacity(255);

        sprite->getStock()->replaceImage(src_cel->getImage(), dst_image);
        image_free(src_image);
      }

      if (undo.isEnabled())
        undo.pushUndoer(new undoers::AddCel(undo.getObjects(), dst_layer, src_cel));

      static_cast<LayerImage*>(dst_layer)->addCel(src_cel);
    }
  }

  undo.commit();

  document->notifyCelMoved(src_layer, src_frame, dst_layer, dst_frame);
  set_frame_to_handle(NULL, FrameNumber(0), NULL, FrameNumber(0));
}
Example #2
0
void CopyCelCommand::onExecute(Context* context)
{
  ActiveDocumentWriter document(context);
  copy_cel(document);
}