示例#1
0
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
void RotateCommand::onExecute(Context* context)
{
  {
    Site site = context->activeSite();
    CelList cels;
    bool rotateSprite = false;

    // Flip the mask or current cel
    if (m_flipMask) {
      auto range = App::instance()->timeline()->range();
      if (range.enabled())
        cels = get_unique_cels(site.sprite(), range);
      else if (site.cel()) {
        // If we want to rotate the visible mask for the current cel,
        // we can go to MovingPixelsState.
        if (static_cast<app::Document*>(site.document())->isMaskVisible()) {
          // Select marquee tool
          if (tools::Tool* tool = App::instance()->toolBox()
              ->getToolById(tools::WellKnownTools::RectangularMarquee)) {
            ToolBar::instance()->selectTool(tool);
            current_editor->startSelectionTransformation(gfx::Point(0, 0), m_angle);
            return;
          }
        }

        cels.push_back(site.cel());
      }
    }
    // Flip the whole sprite
    else if (site.sprite()) {
      for (Cel* cel : site.sprite()->uniqueCels())
        cels.push_back(cel);

      rotateSprite = true;
    }

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

    ContextReader reader(context);
    {
      RotateJob job(reader, m_angle, cels, rotateSprite);
      job.startJob();
      job.waitJob();
    }
    reader.document()->generateMaskBoundaries();
    update_screen_for_document(reader.document());
  }
}
void FilterManagerImpl::applyToTarget()
{
  const bool paletteChange = paletteHasChanged();
  bool cancelled = false;

  CelList cels;

  switch (m_celsTarget) {

    case CelsTarget::Selected: {
      auto range = App::instance()->timeline()->range();
      if (range.enabled())
        cels = get_unlocked_unique_cels(m_site.sprite(), range);
      else if (m_site.cel() &&
               m_site.layer() &&
               m_site.layer()->isEditable()) {
        cels.push_back(m_site.cel());
      }
      break;
    }

    case CelsTarget::All: {
      for (Cel* cel : m_site.sprite()->uniqueCels()) {
        if (cel->layer()->isEditable())
          cels.push_back(cel);
      }
      break;
    }
  }

  if (cels.empty() && !paletteChange) {
    // We don't have images/palette changes to do (there will not be a
    // transaction).
    return;
  }

  // Initialize writting operation
  ContextReader reader(m_context);
  ContextWriter writer(reader);
  m_transaction.reset(new Transaction(writer.context(), m_filter->getName(), ModifyDocument));

  m_progressBase = 0.0f;
  m_progressWidth = (cels.size() > 0 ? 1.0f / cels.size(): 1.0f);

  std::set<ObjectId> visited;

  // Palette change
  if (paletteChange) {
    Palette newPalette = *getNewPalette();
    restoreSpritePalette();
    m_transaction->execute(
      new cmd::SetPalette(m_site.sprite(),
                          m_site.frame(), &newPalette));
  }

  // For each target image
  for (auto it = cels.begin();
       it != cels.end() && !cancelled;
       ++it) {
    Image* image = (*it)->image();

    // Avoid applying the filter two times to the same image
    if (visited.find(image->id()) == visited.end()) {
      visited.insert(image->id());
      applyToCel(*it);
    }

    // Is there a delegate to know if the process was cancelled by the user?
    if (m_progressDelegate)
      cancelled = m_progressDelegate->isCancelled();

    // Make progress
    m_progressBase += m_progressWidth;
  }

  // Reset m_oldPalette to avoid restoring the color palette
  m_oldPalette.reset(nullptr);
}