예제 #1
0
bool LinkCelsCommand::onEnabled(Context* context)
{
  if (context->checkFlags(ContextFlags::ActiveDocumentIsWritable)) {
    // TODO the range of selected frames should be in doc::Site.
    Timeline::Range range = App::instance()->getMainWindow()->getTimeline()->range();
    return (range.enabled() && range.frames() > 1);
  }
  else
    return false;
}
예제 #2
0
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);
}
예제 #3
0
void NewFrameTagCommand::onExecute(Context* context)
{
  const ContextReader reader(context);
  const Sprite* sprite(reader.sprite());
  frame_t from = reader.frame();
  frame_t to = reader.frame();

  Timeline::Range range = App::instance()->getMainWindow()->getTimeline()->range();
  if (range.enabled() &&
      (range.type() == DocumentRange::kFrames ||
       range.type() == DocumentRange::kCels)) {
    from = range.frameBegin();
    to = range.frameEnd();
  }

  base::UniquePtr<FrameTag> frameTag(new FrameTag(from, to));
  FrameTagWindow window(sprite, frameTag);
  if (!window.show())
    return;

  window.rangeValue(from, to);
  frameTag->setFrameRange(from, to);
  frameTag->setName(window.nameValue());
  frameTag->setColor(window.colorValue());
  frameTag->setAniDir(window.aniDirValue());

  {
    ContextWriter writer(reader);
    Transaction transaction(writer.context(), "New Frames Tag");
    transaction.execute(new cmd::AddFrameTag(writer.sprite(), frameTag));
    frameTag.release();
    transaction.commit();
  }

  App::instance()->getMainWindow()->getTimeline()->invalidate();
}
예제 #4
0
void RemoveLayerCommand::onExecute(Context* context)
{
  std::string layer_name;
  ContextWriter writer(context);
  Document* document(writer.document());
  Layer* layer(writer.layer());
  {
    UndoTransaction undoTransaction(writer.context(), "Remove Layer");

    // TODO the range of selected layer should be in the DocumentLocation.
    Timeline::Range range = App::instance()->getMainWindow()->getTimeline()->range();
    if (range.enabled()) {
      Sprite* sprite = writer.sprite();

      // TODO indexes in timeline are inverted!! fix that for a future release
      for (LayerIndex layer = sprite->countLayers() - LayerIndex(range.layerBegin()+1),
             end = sprite->countLayers() - LayerIndex(range.layerEnd()+2);
           layer != end; --layer) {
        document->getApi().removeLayer(sprite->indexToLayer(layer));
      }
    }
    else {
      layer_name = layer->getName();
      document->getApi().removeLayer(layer);
    }

    undoTransaction.commit();
  }
  update_screen_for_document(document);

  StatusBar::instance()->invalidate();
  if (!layer_name.empty())
    StatusBar::instance()->showTip(1000, "Layer `%s' removed", layer_name.c_str());
  else
    StatusBar::instance()->showTip(1000, "Layers removed");
}
예제 #5
0
void LinkCelsCommand::onExecute(Context* context)
{
  ContextWriter writer(context);
  Document* document(writer.document());
  bool nonEditableLayers = false;
  {
    // TODO the range of selected frames should be in doc::Site.
    Timeline::Range range = App::instance()->getMainWindow()->getTimeline()->range();
    if (!range.enabled())
      return;

    Transaction transaction(writer.context(), friendlyName());
    Sprite* sprite = writer.sprite();
    frame_t begin = range.frameBegin();
    frame_t end = range.frameEnd();

    for (LayerIndex layerIdx = range.layerBegin(); layerIdx <= range.layerEnd(); ++layerIdx) {
      Layer* layer = sprite->indexToLayer(layerIdx);
      if (!layer->isImage())
        continue;

      if (!layer->isEditable()) {
        nonEditableLayers = true;
        continue;
      }

      LayerImage* layerImage = static_cast<LayerImage*>(layer);
      for (frame_t frame=begin; frame < end+1; ++frame) {
        Cel* cel = layerImage->cel(frame);
        if (cel) {
          for (frame = cel->frame()+1;
               frame < end+1; ++frame) {
            transaction.execute(
              new cmd::CopyCel(
                layerImage, cel->frame(),
                layerImage, frame,
                true));         // true = force links
          }
          break;
        }
      }
    }

    transaction.commit();
  }

  if (nonEditableLayers)
    StatusBar::instance()->showTip(1000,
      "There are locked layers");

  update_screen_for_document(document);
}
예제 #6
0
void SetLoopSectionCommand::onExecute(Context* ctx)
{
  doc::Document* doc = ctx->activeDocument();
  if (!doc)
    return;

  doc::Sprite* sprite = doc->sprite();
  doc::frame_t begin = m_begin;
  doc::frame_t end = m_end;
  bool on = false;

  switch (m_action) {

    case Action::Auto: {
      Timeline::Range range = App::instance()->getMainWindow()->getTimeline()->range();
      if (range.enabled() && (range.frames() > 1)) {
        begin = range.frameBegin();
        end = range.frameEnd();
        on = true;
      }
      else {
        on = false;
      }
      break;
    }

    case Action::On:
      on = true;
      break;

    case Action::Off:
      on = false;
      break;

  }

  doc::FrameTag* loopTag = get_loop_tag(sprite);
  if (on) {
    if (!loopTag) {
      loopTag = create_loop_tag(begin, end);

      ContextWriter writer(ctx);
      Transaction transaction(writer.context(), "Add Loop");
      transaction.execute(new cmd::AddFrameTag(sprite, loopTag));
      transaction.commit();
    }
    else if (loopTag->fromFrame() != begin ||
             loopTag->toFrame() != end) {
      ContextWriter writer(ctx);
      Transaction transaction(writer.context(), "Set Loop Range");
      transaction.execute(new cmd::SetFrameTagRange(loopTag, begin, end));
      transaction.commit();
    }
    else {
      Command* cmd = CommandsModule::instance()->getCommandByName(CommandId::FrameTagProperties);
      ctx->executeCommand(cmd);
    }
  }
  else {
    if (loopTag) {
      ContextWriter writer(ctx);
      Transaction transaction(writer.context(), "Remove Loop");
      transaction.execute(new cmd::RemoveFrameTag(sprite, loopTag));
      transaction.commit();
    }
  }

  App::instance()->getMainWindow()->getTimeline()->invalidate();
}