コード例 #1
0
ファイル: cmd_rotate.cpp プロジェクト: 1007650105/aseprite
void RotateCommand::onExecute(Context* context)
{
  ContextReader reader(context);
  {
    CelList cels;
    bool rotateSprite = false;

    // Flip the mask or current cel
    if (m_flipMask) {
      DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range();
      if (range.enabled())
        cels = get_unique_cels(reader.sprite(), range);
      else if (reader.cel())
        cels.push_back(reader.cel());
    }
    // Flip the whole sprite
    else if (reader.sprite()) {
      for (Cel* cel : reader.sprite()->uniqueCels())
        cels.push_back(cel);

      rotateSprite = true;
    }

    if (cels.empty())           // Nothing to do
      return;

    RotateJob job(reader, m_angle, cels, rotateSprite);
    job.startJob();
    job.waitJob();
  }
  reader.document()->generateMaskBoundaries();
  update_screen_for_document(reader.document());
}
コード例 #2
0
ファイル: status_bar.cpp プロジェクト: dejavvu/aseprite
void StatusBar::onCelOpacityChange()
{
  try {
    ContextWriter writer(UIContext::instance(), 500);

    DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range();
    if (range.enabled()) {
      for (Cel* cel : get_unique_cels(writer.sprite(), range))
        cel->setOpacity(m_slider->getValue());
    }
    else {
      Cel* cel = writer.cel();
      if (cel) {
        // Update the opacity
        cel->setOpacity(m_slider->getValue());
      }
    }

    // Update the editors
    update_screen_for_document(writer.document());
  }
  catch (LockedDocumentException&) {
    // do nothing
  }
}
コード例 #3
0
bool ReverseFramesCommand::onEnabled(Context* context)
{
  DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range();

  return
    context->checkFlags(ContextFlags::ActiveDocumentIsWritable) &&
    range.enabled() &&
    range.frames() >= 2;         // We need at least 2 frames to reverse
}
コード例 #4
0
void ReverseFramesCommand::onExecute(Context* context)
{
  DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range();
  if (!range.enabled())
    return;                     // Nothing to do

  Document* doc = context->activeDocument();

  reverse_frames(doc, range);

  update_screen_for_document(doc);
}
コード例 #5
0
void reverse_frames(Document* doc, const DocumentRange& range)
{
  const app::Context* context = static_cast<app::Context*>(doc->context());
  const ContextReader reader(context);
  ContextWriter writer(reader);
  Transaction transaction(writer.context(), "Reverse Frames");
  DocumentApi api = doc->getApi(transaction);
  Sprite* sprite = doc->sprite();
  frame_t frameBegin, frameEnd;
  int layerBegin, layerEnd;
  bool moveFrames = false;

  switch (range.type()) {
    case DocumentRange::kCels:
      frameBegin = range.frameBegin();
      frameEnd = range.frameEnd();
      layerBegin = range.layerBegin();
      layerEnd = range.layerEnd() + 1;
      break;
    case DocumentRange::kFrames:
      frameBegin = range.frameBegin();
      frameEnd = range.frameEnd();
      moveFrames = true;
      break;
    case DocumentRange::kLayers:
      frameBegin = frame_t(0);
      frameEnd = sprite->totalFrames()-1;
      layerBegin = range.layerBegin();
      layerEnd = range.layerEnd() + 1;
      break;
  }

  if (moveFrames) {
    for (frame_t frameRev = frameEnd+1;
         frameRev > frameBegin;
         --frameRev) {
      api.moveFrame(sprite, frameBegin, frameRev);
    }
  }
  else {
    std::vector<Layer*> layers;
    sprite->getLayersList(layers);

    for (int layerIdx = layerBegin; layerIdx != layerEnd; ++layerIdx) {
      for (frame_t frame = frameBegin,
             frameRev = frameEnd;
           frame != (frameBegin+frameEnd)/2+1;
           ++frame, --frameRev) {
        LayerImage* layer = static_cast<LayerImage*>(layers[layerIdx]);
        api.swapCel(layer, frame, frameRev);
      }
    }
  }

  transaction.commit();
}
コード例 #6
0
  void onCommitChange() {
    base::ScopedValue<bool> switchSelf(m_selfUpdate, true, false);

    m_timer.stop();

    const int newOpacity = opacityValue();
    const int count = countCels();

    if ((count > 1) ||
        (count == 1 && m_cel && (newOpacity != m_cel->opacity() ||
                                 m_userData != m_cel->data()->userData()))) {
      try {
        ContextWriter writer(UIContext::instance());
        Transaction transaction(writer.context(), "Set Cel Properties");

        DocumentRange range;
        if (m_range.enabled())
          range = m_range;
        else {
          range.startRange(m_cel->layer(), m_cel->frame(), DocumentRange::kCels);
          range.endRange(m_cel->layer(), m_cel->frame());
        }

        Sprite* sprite = m_document->sprite();
        for (Cel* cel : sprite->uniqueCels(range.selectedFrames())) {
          if (range.contains(cel->layer())) {
            if (!cel->layer()->isBackground() && newOpacity != cel->opacity()) {
              transaction.execute(new cmd::SetCelOpacity(cel, newOpacity));
            }

            if (m_newUserData &&
                m_userData != cel->data()->userData()) {
              transaction.execute(new cmd::SetUserData(cel->data(), m_userData));

              // Redraw timeline because the cel's user data/color
              // might have changed.
              App::instance()->timeline()->invalidate();
            }
          }
        }

        transaction.commit();
      }
      catch (const std::exception& e) {
        Console::showException(e);
      }

      update_screen_for_document(m_document);
    }
  }
コード例 #7
0
ファイル: cmd_copy.cpp プロジェクト: Ravnox/aseprite
void CopyCommand::onExecute(Context* context)
{
  const ContextReader reader(context);

  // Copy a range from the timeline.
  DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range();
  if (range.enabled()) {
    clipboard::copy_range(reader, range);
  }
  else if (reader.site()->document() &&
           static_cast<const app::Document*>(reader.site()->document())->isMaskVisible() &&
           reader.site()->image()) {
    clipboard::copy(reader);
  }
}
コード例 #8
0
Status CommandReplyBuilder::addOutputDocs(DocumentRange outputDocs) {
    invariant(_state == State::kOutputDocs);
    auto rangeData = outputDocs.data();
    auto dataSize = rangeData.length();
    _builder.appendBuf(rangeData.data(), dataSize);
    return Status::OK();
}
コード例 #9
0
void ClearCommand::onExecute(Context* context)
{
  // Clear of several frames is handled with ClearCel command.
  DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range();
  if (range.enabled()) {
    Command* subCommand = NULL;

    switch (range.type()) {
      case DocumentRange::kCels:
        subCommand = CommandsModule::instance()->getCommandByName(CommandId::ClearCel);
        break;
      case DocumentRange::kFrames:
        subCommand = CommandsModule::instance()->getCommandByName(CommandId::RemoveFrame);
        break;
      case DocumentRange::kLayers:
        subCommand = CommandsModule::instance()->getCommandByName(CommandId::RemoveLayer);
        break;
    }

    if (subCommand) {
      context->executeCommand(subCommand);
      return;
    }
  }

  // TODO add support to clear the mask in the selected range of frames.

  ContextWriter writer(context);
  Document* document = writer.document();
  bool visibleMask = document->isMaskVisible();

  if (!writer.cel())
    return;

  {
    Transaction transaction(writer.context(), "Clear");
    transaction.execute(new cmd::ClearMask(writer.cel()));
    if (visibleMask)
      transaction.execute(new cmd::DeselectMask(document));
    transaction.commit();
  }
  if (visibleMask)
    document->generateMaskBoundaries();
  update_screen_for_document(document);
}
コード例 #10
0
ファイル: command_reply_builder.cpp プロジェクト: qihsh/mongo
Status CommandReplyBuilder::addOutputDocs(DocumentRange outputDocs) {
    invariant(_state == State::kOutputDocs);
    auto rangeData = outputDocs.data();
    auto dataSize = rangeData.length();
    auto hasSpace = _hasSpaceFor(dataSize);
    if (!hasSpace.isOK()) {
        return hasSpace;
    }

    _builder.appendBuf(rangeData.data(), dataSize);
    return Status::OK();
}
コード例 #11
0
// 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;
}
コード例 #12
0
Status LegacyReplyBuilder::addOutputDocs(DocumentRange docs) {
    invariant(_state == State::kOutputDocs);
    invariant(_allowAddingOutputDocs);

    auto dataSize = docs.data().length();

    auto hasSpace = _hasSpaceFor(dataSize);
    if (!hasSpace.isOK()) {
        return hasSpace;
    }

    // The temporary obj is used to address the case when where is not enough space.
    // BSONArray overhead can not be estimated upfront.
    std::vector<BSONObj> docsTmp{};
    std::size_t lenTmp = 0;
    std::size_t tmpIndex(_currentIndex);
    for (auto&& it : docs) {
        docsTmp.emplace_back(it.getOwned());
        lenTmp += BSONObjBuilder::numStr(++tmpIndex).length() + 2;  // space for storing array index
    }

    hasSpace = _hasSpaceFor(dataSize + lenTmp);
    if (!hasSpace.isOK()) {
        return hasSpace;
    }

    // vector::insert instead of swap allows to call addOutputDoc(s) multiple times
    _outputDocs.insert(_outputDocs.end(),
                       std::make_move_iterator(docsTmp.begin()),
                       std::make_move_iterator(docsTmp.end()));

    _currentIndex = tmpIndex;
    _currentLength += lenTmp;
    _currentLength += dataSize;
    return Status::OK();
}
コード例 #13
0
ファイル: standby_state.cpp プロジェクト: tommo/aseprite
bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg)
{
  if (editor->hasCapture())
    return true;

  UIContext* context = UIContext::instance();
  tools::Ink* clickedInk = editor->getCurrentEditorInk();
  Site site;
  editor->getSite(&site);
  app::Document* document = static_cast<app::Document*>(site.document());
  Layer* layer = site.layer();

  // When an editor is clicked the current view is changed.
  context->setActiveView(editor->getDocumentView());

  // Start scroll loop
  if (checkForScroll(editor, msg) || checkForZoom(editor, msg))
    return true;

  // Move cel X,Y coordinates
  if (clickedInk->isCelMovement()) {
    // Handle "Auto Select Layer"
    if (editor->isAutoSelectLayer()) {
      gfx::Point cursor = editor->screenToEditor(msg->position());

      ColorPicker picker;
      picker.pickColor(site, cursor, ColorPicker::FromComposition);

      DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range();

      // Change layer only when the layer is diffrent from current one, and
      // the range we selected is not with multiple cels.
      bool layerChanged = (layer != picker.layer());
      bool rangeEnabled = range.enabled();
      bool rangeSingleCel = ((range.type() == DocumentRange::kCels) &&
                             (range.layers() == 1) && (range.frames() == 1));

      if (layerChanged && (!rangeEnabled || rangeSingleCel)) {
        layer = picker.layer();
        if (layer) {
          editor->setLayer(layer);
          editor->flashCurrentLayer();
        }
      }
    }

    if ((layer) &&
        (layer->type() == ObjectType::LayerImage)) {
      // TODO we should be able to move the `Background' with tiled mode
      if (layer->isBackground()) {
        StatusBar::instance()->showTip(1000,
          "The background layer cannot be moved");
      }
      else if (!layer->isVisible()) {
        StatusBar::instance()->showTip(1000,
          "Layer '%s' is hidden", layer->name().c_str());
      }
      else if (!layer->isMovable() || !layer->isEditable()) {
        StatusBar::instance()->showTip(1000,
          "Layer '%s' is locked", layer->name().c_str());
      }
      else if (!layer->cel(editor->frame())) {
        StatusBar::instance()->showTip(1000,
          "Cel is empty, nothing to move");
      }
      else {
        // Change to MovingCelState
        editor->setState(EditorStatePtr(new MovingCelState(editor, msg)));
      }
    }

    return true;
  }

  // Call the eyedropper command
  if (clickedInk->isEyedropper()) {
    editor->captureMouse();
    callEyedropper(editor);
    return true;
  }

  if (clickedInk->isSelection()) {
    // Transform selected pixels
    if (editor->isActive() &&
        document->isMaskVisible() &&
        m_decorator->getTransformHandles(editor)) {
      TransformHandles* transfHandles = m_decorator->getTransformHandles(editor);

      // Get the handle covered by the mouse.
      HandleType handle = transfHandles->getHandleAtPoint(editor,
        msg->position(),
        document->getTransformation());

      if (handle != NoHandle) {
        int x, y, opacity;
        Image* image = site.image(&x, &y, &opacity);
        if (layer && image) {
          if (!layer->isEditable()) {
            StatusBar::instance()->showTip(1000,
              "Layer '%s' is locked", layer->name().c_str());
            return true;
          }

          // Change to MovingPixelsState
          transformSelection(editor, msg, handle);
        }
        return true;
      }
    }

    // Move selected pixels
    if (layer && editor->isInsideSelection() && msg->left()) {
      if (!layer->isEditable()) {
        StatusBar::instance()->showTip(1000,
          "Layer '%s' is locked", layer->name().c_str());
        return true;
      }

      // Change to MovingPixelsState
      transformSelection(editor, msg, MoveHandle);
      return true;
    }
  }

  // Move symmetry
  gfx::Rect box1, box2;
  if (m_decorator->getSymmetryHandles(editor, box1, box2) &&
      (box1.contains(msg->position()) ||
       box2.contains(msg->position()))) {
    auto& symmetry = Preferences::instance().document(editor->document()).symmetry;
    auto mode = symmetry.mode();
    bool horz = (mode == app::gen::SymmetryMode::HORIZONTAL);
    auto& axis = (horz ? symmetry.xAxis:
                         symmetry.yAxis);
    editor->setState(
      EditorStatePtr(new MovingSymmetryState(editor, msg,
                                             mode, axis)));
    return true;
  }

  // Start the Tool-Loop
  if (layer) {
    tools::ToolLoop* toolLoop = create_tool_loop(editor, context);
    if (toolLoop) {
      EditorStatePtr newState(new DrawingState(toolLoop));
      editor->setState(newState);

      static_cast<DrawingState*>(newState.get())
        ->initToolLoop(editor, msg);
    }
    return true;
  }

  return true;
}
コード例 #14
0
static DocumentRange drop_range_op(
  Document* doc, Op op, const DocumentRange& from,
  DocumentRangePlace place, const DocumentRange& to)
{
  if (place != kDocumentRangeBefore &&
      place != kDocumentRangeAfter) {
    ASSERT(false);
    throw std::invalid_argument("Invalid 'place' argument");
  }

  Sprite* sprite = doc->sprite();

  // Check noop/trivial/do nothing cases, i.e., move a range to the same place.
  // Also check invalid cases, like moving a Background layer.
  switch (from.type()) {
    case DocumentRange::kCels:
      if (from == to)
        return from;
      break;
    case DocumentRange::kFrames:
      if (op == Move) {
        if ((to.frameBegin() >= from.frameBegin() && to.frameEnd() <= from.frameEnd()) ||
            (place == kDocumentRangeBefore && to.frameBegin() == from.frameEnd()+1) ||
            (place == kDocumentRangeAfter && to.frameEnd() == from.frameBegin()-1))
          return from;
      }
      break;
    case DocumentRange::kLayers:
      if (op == Move) {
        if ((to.layerBegin() >= from.layerBegin() && to.layerEnd() <= from.layerEnd()) ||
            (place == kDocumentRangeBefore && to.layerBegin() == from.layerEnd()+1) ||
            (place == kDocumentRangeAfter && to.layerEnd() == from.layerBegin()-1))
          return from;

        // We cannot move the background
        for (LayerIndex i = from.layerBegin(); i <= from.layerEnd(); ++i)
          if (sprite->indexToLayer(i)->isBackground())
            throw std::runtime_error("The background layer cannot be moved");

        // Before background
        if (place == kDocumentRangeBefore) {
          Layer* background = sprite->indexToLayer(to.layerBegin());
          if (background && background->isBackground())
            throw std::runtime_error("You cannot move something below the background layer");
        }
      }
      break;
  }

  const char* undoLabel = NULL;
  switch (op) {
    case Move: undoLabel = "Move Range"; break;
    case Copy: undoLabel = "Copy Range"; break;
    default:
      ASSERT(false);
      throw std::invalid_argument("Invalid 'op' argument");
  }
  DocumentRange resultRange;

  {
    const app::Context* context = static_cast<app::Context*>(doc->context());
    const ContextReader reader(context);
    ContextWriter writer(reader);
    Transaction transaction(writer.context(), undoLabel, ModifyDocument);
    DocumentApi api = doc->getApi(transaction);

    // TODO Try to add the range with just one call to DocumentApi
    // methods, to avoid generating a lot of SetCelFrame undoers (see
    // DocumentApi::setCelFramePosition).

    switch (from.type()) {

      case DocumentRange::kCels:
        {
          std::vector<Layer*> layers;
          sprite->getLayersList(layers);

          int srcLayerBegin, srcLayerStep, srcLayerEnd;
          int dstLayerBegin, dstLayerStep;
          frame_t srcFrameBegin, srcFrameStep, srcFrameEnd;
          frame_t dstFrameBegin, dstFrameStep;

          if (to.layerBegin() <= from.layerBegin()) {
            srcLayerBegin = from.layerBegin();
            srcLayerStep = 1;
            srcLayerEnd = from.layerEnd()+1;
            dstLayerBegin = to.layerBegin();
            dstLayerStep = 1;
          }
          else {
            srcLayerBegin = from.layerEnd();
            srcLayerStep = -1;
            srcLayerEnd = from.layerBegin()-1;
            dstLayerBegin = to.layerEnd();
            dstLayerStep = -1;
          }

          if (to.frameBegin() <= from.frameBegin()) {
            srcFrameBegin = from.frameBegin();
            srcFrameStep = frame_t(1);
            srcFrameEnd = from.frameEnd()+1;
            dstFrameBegin = to.frameBegin();
            dstFrameStep = frame_t(1);
          }
          else {
            srcFrameBegin = from.frameEnd();
            srcFrameStep = frame_t(-1);
            srcFrameEnd = from.frameBegin()-1;
            dstFrameBegin = to.frameEnd();
            dstFrameStep = frame_t(-1);
          }

          for (int srcLayerIdx = srcLayerBegin,
                 dstLayerIdx = dstLayerBegin; srcLayerIdx != srcLayerEnd; ) {
            for (frame_t srcFrame = srcFrameBegin,
                   dstFrame = dstFrameBegin; srcFrame != srcFrameEnd; ) {
              LayerImage* srcLayer = static_cast<LayerImage*>(layers[srcLayerIdx]);
              LayerImage* dstLayer = static_cast<LayerImage*>(layers[dstLayerIdx]);

              switch (op) {
                case Move: api.moveCel(srcLayer, srcFrame, dstLayer, dstFrame); break;
                case Copy: api.copyCel(srcLayer, srcFrame, dstLayer, dstFrame); break;
              }

              srcFrame += srcFrameStep;
              dstFrame += dstFrameStep;
            }
            srcLayerIdx += srcLayerStep;
            dstLayerIdx += dstLayerStep;
          }

          resultRange = to;
        }
        break;

      case DocumentRange::kFrames:
        {
          frame_t srcFrameBegin = 0, srcFrameStep, srcFrameEnd = 0;
          frame_t dstFrameBegin = 0, dstFrameStep;

          switch (op) {

            case Move:
              if (place == kDocumentRangeBefore) {
                if (to.frameBegin() <= from.frameBegin()) {
                  srcFrameBegin = from.frameBegin();
                  srcFrameStep = frame_t(1);
                  srcFrameEnd = from.frameEnd()+1;
                  dstFrameBegin = to.frameBegin();
                  dstFrameStep = frame_t(1);
                }
                else {
                  srcFrameBegin = from.frameEnd();
                  srcFrameStep = frame_t(-1);
                  srcFrameEnd = from.frameBegin()-1;
                  dstFrameBegin = to.frameBegin();
                  dstFrameStep = frame_t(-1);
                }
              }
              else if (place == kDocumentRangeAfter) {
                if (to.frameEnd() <= from.frameBegin()) {
                  srcFrameBegin = from.frameBegin();
                  srcFrameStep = frame_t(1);
                  srcFrameEnd = from.frameEnd()+1;
                  dstFrameBegin = to.frameEnd()+1;
                  dstFrameStep = frame_t(1);
                }
                else {
                  srcFrameBegin = from.frameEnd();
                  srcFrameStep = frame_t(-1);
                  srcFrameEnd = from.frameBegin()-1;
                  dstFrameBegin = to.frameEnd()+1;
                  dstFrameStep = frame_t(-1);
                }
              }
              break;

            case Copy:
              if (place == kDocumentRangeBefore) {
                if (to.frameBegin() <= from.frameBegin()) {
                  srcFrameBegin = from.frameBegin();
                  srcFrameStep = frame_t(2);
                  srcFrameEnd = from.frameBegin() + 2*from.frames();
                  dstFrameBegin = to.frameBegin();
                  dstFrameStep = frame_t(1);
                }
                else {
                  srcFrameBegin = from.frameEnd();
                  srcFrameStep = frame_t(-1);
                  srcFrameEnd = from.frameBegin()-1;
                  dstFrameBegin = to.frameBegin();
                  dstFrameStep = frame_t(0);
                }
              }
              else if (place == kDocumentRangeAfter) {
                if (to.frameEnd() <= from.frameBegin()) {
                  srcFrameBegin = from.frameBegin();
                  srcFrameStep = frame_t(2);
                  srcFrameEnd = from.frameBegin() + 2*from.frames();
                  dstFrameBegin = to.frameEnd()+1;
                  dstFrameStep = frame_t(1);
                }
                else {
                  srcFrameBegin = from.frameEnd();
                  srcFrameStep = frame_t(-1);
                  srcFrameEnd = from.frameBegin()-1;
                  dstFrameBegin = to.frameEnd()+1;
                  dstFrameStep = frame_t(0);
                }
              }
              break;
          }

          for (frame_t srcFrame = srcFrameBegin,
                 dstFrame = dstFrameBegin; srcFrame != srcFrameEnd; ) {
            switch (op) {
              case Move: api.moveFrame(sprite, srcFrame, dstFrame); break;
              case Copy: api.copyFrame(sprite, srcFrame, dstFrame); break;
            }
            srcFrame += srcFrameStep;
            dstFrame += dstFrameStep;
          }

          if (place == kDocumentRangeBefore) {
            resultRange.startRange(LayerIndex::NoLayer, frame_t(to.frameBegin()), from.type());
            resultRange.endRange(LayerIndex::NoLayer, frame_t(to.frameBegin()+from.frames()-1));
          }
          else if (place == kDocumentRangeAfter) {
            resultRange.startRange(LayerIndex::NoLayer, frame_t(to.frameEnd()+1), from.type());
            resultRange.endRange(LayerIndex::NoLayer, frame_t(to.frameEnd()+1+from.frames()-1));
          }

          if (op == Move && from.frameBegin() < to.frameBegin())
            resultRange.displace(0, -from.frames());
        }
        break;

      case DocumentRange::kLayers:
        {
          std::vector<Layer*> layers;
          sprite->getLayersList(layers);

          if (layers.empty())
            break;

          switch (op) {

            case Move:
              if (place == kDocumentRangeBefore) {
                for (LayerIndex i = from.layerBegin(); i <= from.layerEnd(); ++i) {
                  api.restackLayerBefore(
                    layers[i],
                    layers[to.layerBegin()]);
                }
              }
              else if (place == kDocumentRangeAfter) {
                for (LayerIndex i = from.layerEnd(); i >= from.layerBegin(); --i) {
                  api.restackLayerAfter(
                    layers[i],
                    layers[to.layerEnd()]);
                }
              }
              break;

            case Copy:
              if (place == kDocumentRangeBefore) {
                for (LayerIndex i = from.layerBegin(); i <= from.layerEnd(); ++i) {
                  api.duplicateLayerBefore(
                    layers[i],
                    layers[to.layerBegin()]);
                }
              }
              else if (place == kDocumentRangeAfter) {
                for (LayerIndex i = from.layerEnd(); i >= from.layerBegin(); --i) {
                  api.duplicateLayerAfter(
                    layers[i],
                    layers[to.layerEnd()]);
                }
              }
              break;
          }

          if (place == kDocumentRangeBefore) {
            resultRange.startRange(LayerIndex(to.layerBegin()), frame_t(-1), from.type());
            resultRange.endRange(LayerIndex(to.layerBegin()+from.layers()-1), frame_t(-1));
          }
          else if (place == kDocumentRangeAfter) {
            resultRange.startRange(LayerIndex(to.layerEnd()+1), frame_t(-1), from.type());
            resultRange.endRange(LayerIndex(to.layerEnd()+1+from.layers()-1), frame_t(-1));
          }

          if (op == Move && from.layerBegin() < to.layerBegin())
            resultRange.displace(-from.layers(), 0);
        }
        break;
    }

    transaction.commit();
  }

  return resultRange;
}
コード例 #15
0
inline DocumentRange range(int fromLayer, frame_t fromFrNum, int toLayer, frame_t toFrNum, DocumentRange::Type type) {
  DocumentRange r;
  r.startRange(LayerIndex(fromLayer), fromFrNum, type);
  r.endRange(LayerIndex(toLayer), toFrNum);
  return r;
}
コード例 #16
0
inline DocumentRange range(Layer* fromLayer, frame_t fromFrNum, Layer* toLayer, frame_t toFrNum, DocumentRange::Type type) {
  DocumentRange r;
  r.startRange(fromLayer->sprite()->layerToIndex(fromLayer), fromFrNum, type);
  r.endRange(toLayer->sprite()->layerToIndex(toLayer), toFrNum);
  return r;
}