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 InvertMaskCommand::onExecute(Context* context) { bool hasMask = false; { const ContextReader reader(context); if (reader.document()->isMaskVisible()) hasMask = true; } // without mask?... if (!hasMask) { // so we select all Command* mask_all_cmd = CommandsModule::instance()->getCommandByName(CommandId::MaskAll); context->executeCommand(mask_all_cmd); } // invert the current mask else { ContextWriter writer(context); Document* document(writer.document()); Sprite* sprite(writer.sprite()); // Select all the sprite area base::UniquePtr<Mask> mask(new Mask()); mask->replace(sprite->bounds()); // Remove in the new mask the current sprite marked region const gfx::Rect& maskBounds = document->mask()->bounds(); doc::fill_rect(mask->bitmap(), maskBounds.x, maskBounds.y, maskBounds.x + maskBounds.w-1, maskBounds.y + maskBounds.h-1, 0); Mask* curMask = document->mask(); if (curMask->bitmap()) { // Copy the inverted region in the new mask (we just modify the // document's mask temporaly here) curMask->freeze(); curMask->invert(); doc::copy_image(mask->bitmap(), curMask->bitmap(), curMask->bounds().x, curMask->bounds().y); curMask->invert(); curMask->unfreeze(); } // We need only need the area inside the sprite mask->intersect(sprite->bounds()); // Set the new mask Transaction transaction(writer.context(), "Mask Invert", DoesntModifyDocument); transaction.execute(new cmd::SetMask(document, mask)); transaction.commit(); document->generateMaskBoundaries(); update_screen_for_document(document); } }
void InvertMaskCommand::onExecute(Context* context) { bool hasMask = false; { const ActiveDocumentReader document(context); if (document->isMaskVisible()) hasMask = true; } // without mask?... if (!hasMask) { // so we select all Command* mask_all_cmd = CommandsModule::instance()->getCommandByName(CommandId::MaskAll); context->executeCommand(mask_all_cmd); } // invert the current mask else { ActiveDocumentWriter document(context); Sprite* sprite(document->getSprite()); UndoTransaction undo(document, "Mask Invert", undo::DoesntModifyDocument); if (undo.isEnabled()) undo.pushUndoer(new undoers::SetMask(undo.getObjects(), document)); /* create a new mask */ UniquePtr<Mask> mask(new Mask()); /* select all the sprite area */ mask->replace(0, 0, sprite->getWidth(), sprite->getHeight()); /* remove in the new mask the current sprite marked region */ const gfx::Rect& maskBounds = document->getMask()->getBounds(); image_rectfill(mask->getBitmap(), maskBounds.x, maskBounds.y, maskBounds.x + maskBounds.w-1, maskBounds.y + maskBounds.h-1, 0); // Invert the current mask in the sprite document->getMask()->invert(); if (document->getMask()->getBitmap()) { // Copy the inverted region in the new mask image_copy(mask->getBitmap(), document->getMask()->getBitmap(), document->getMask()->getBounds().x, document->getMask()->getBounds().y); } // We need only need the area inside the sprite mask->intersect(0, 0, sprite->getWidth(), sprite->getHeight()); // Set the new mask document->setMask(mask); undo.commit(); document->generateMaskBoundaries(); update_screen_for_document(document); } }
void PixelsMovement::setMaskColor(bool opaque, color_t mask_color) { ContextWriter writer(m_reader, 1000); m_opaque = opaque; m_maskColor = mask_color; redrawExtraImage(); update_screen_for_document(m_document); }
void UndoCommand::onExecute(Context* context) { ActiveDocumentWriter document(context); DocumentUndo* undo = document->getUndo(); Sprite* sprite = document->getSprite(); if (get_config_bool("Options", "UndoGotoModified", true)) { SpritePosition spritePosition; if (m_type == Undo) spritePosition = undo->getNextUndoSpritePosition(); else spritePosition = undo->getNextRedoSpritePosition(); if (spritePosition != sprite->getCurrentPosition()) { sprite->setCurrentPosition(spritePosition); current_editor->drawSpriteSafe(0, 0, sprite->getWidth(), sprite->getHeight()); update_screen_for_document(document); ui::dirty_display_flag = true; gui_feedback(); base::this_thread::sleep_for(0.01); } } StatusBar::instance() ->showTip(1000, "%s %s", (m_type == Undo ? "Undid": "Redid"), (m_type == Undo ? undo->getNextUndoLabel(): undo->getNextRedoLabel())); if (m_type == Undo) undo->doUndo(); else undo->doRedo(); document->generateMaskBoundaries(); document->destroyExtraCel(); // Regenerate extras update_screen_for_document(document); }
void RotateCanvasCommand::onExecute(Context* context) { ActiveDocumentReader document(context); { RotateCanvasJob job(document, m_angle); job.startJob(); } document->generateMaskBoundaries(); update_screen_for_document(document); }
void RotateCanvasCommand::onExecute(Context* context) { ContextReader reader(context); { RotateCanvasJob job(reader, m_angle); job.startJob(); } reader.document()->generateMaskBoundaries(); update_screen_for_document(reader.document()); }
void FlattenLayersCommand::onExecute(Context* context) { ContextWriter writer(context); Sprite* sprite = writer.sprite(); { Transaction transaction(writer.context(), "Flatten Layers"); transaction.execute(new cmd::FlattenLayers(sprite)); transaction.commit(); } update_screen_for_document(writer.document()); }
void DeselectMaskCommand::onExecute(Context* context) { ContextWriter writer(context); Doc* document(writer.document()); { Tx tx(writer.context(), "Deselect", DoesntModifyDocument); tx(new cmd::DeselectMask(document)); tx.commit(); } update_screen_for_document(document); }
void PixelsMovement::copyMask() { // Hide the mask (do not deselect it, it will be moved them using // m_transaction.setMaskPosition) Mask emptyMask; { ContextWriter writer(m_reader, 1000); m_document->generateMaskBoundaries(&emptyMask); update_screen_for_document(m_document); } }
void LayerFromBackgroundCommand::onExecute(Context* context) { ContextWriter writer(context); Document* document(writer.document()); { Transaction transaction(writer.context(), "Layer from Background"); document->getApi(transaction).layerFromBackground(writer.layer()); transaction.commit(); } update_screen_for_document(document); }
void UnlinkCelCommand::onExecute(Context* context) { ContextWriter writer(context); Document* document(writer.document()); bool nonEditableLayers = false; { Transaction transaction(writer.context(), "Unlink Cel"); // TODO the range of selected frames should be in doc::Site. auto range = App::instance()->timeline()->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 (frame_t frame = range.frameEnd(), begin = range.frameBegin()-1; frame != begin; --frame) { Cel* cel = layerImage->cel(frame); if (cel && cel->links()) { if (layerImage->isEditable()) transaction.execute(new cmd::UnlinkCel(cel)); else nonEditableLayers = true; } } } } else { Cel* cel = writer.cel(); if (cel && cel->links()) { if (cel->layer()->isEditable()) transaction.execute(new cmd::UnlinkCel(writer.cel())); else nonEditableLayers = true; } } transaction.commit(); } if (nonEditableLayers) StatusBar::instance()->showTip(1000, "There are locked layers"); update_screen_for_document(document); }
void FlattenLayersCommand::onExecute(Context* context) { ActiveDocumentWriter document(context); Sprite* sprite = document->getSprite(); int bgcolor = color_utils::color_for_image(app_get_colorbar()->getBgColor(), sprite->getImgType()); { UndoTransaction undoTransaction(document, "Flatten Layers"); undoTransaction.flattenLayers(bgcolor); undoTransaction.commit(); } update_screen_for_document(document); }
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); }
void DeselectMaskCommand::onExecute(Context* context) { ContextWriter writer(context); Document* document(writer.document()); { Transaction transaction(writer.context(), "Deselect", DoesntModifyDocument); transaction.execute(new cmd::DeselectMask(document)); transaction.commit(); } document->generateMaskBoundaries(); update_screen_for_document(document); }
void RemoveFrameCommand::onExecute(Context* context) { ContextWriter writer(context); Document* document(writer.document()); Sprite* sprite(writer.sprite()); { UndoTransaction undoTransaction(writer.context(), "Remove Frame"); document->getApi().removeFrame(sprite, writer.frame()); undoTransaction.commit(); } update_screen_for_document(document); }
void DeselectMaskCommand::onExecute(Context* context) { ContextWriter writer(context); Document* document(writer.document()); { UndoTransaction undoTransaction(writer.context(), "Mask Deselection", undo::DoesntModifyDocument); document->getApi().deselectMask(); undoTransaction.commit(); } document->generateMaskBoundaries(); update_screen_for_document(document); }
void FlattenLayersCommand::onExecute(Context* context) { ContextWriter writer(context); Document* document = writer.document(); Sprite* sprite = writer.sprite(); { UndoTransaction undoTransaction(writer.context(), "Flatten Layers"); document->getApi().flattenLayers(sprite); undoTransaction.commit(); } update_screen_for_document(writer.document()); }
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); }
void RemoveLayerCommand::onExecute(Context* context) { std::string layerName; ContextWriter writer(context); Document* document(writer.document()); Sprite* sprite(writer.sprite()); { Transaction transaction(writer.context(), "Remove Layer"); DocumentApi api = document->getApi(transaction); const Site* site = writer.site(); if (site->inTimeline() && !site->selectedLayers().empty()) { SelectedLayers selLayers = site->selectedLayers(); selLayers.removeChildrenIfParentIsSelected(); layer_t deletedTopLevelLayers = 0; for (Layer* layer : selLayers) { if (layer->parent() == sprite->root()) ++deletedTopLevelLayers; } if (deletedTopLevelLayers == sprite->root()->layersCount()) { ui::Alert::show("Error<<You cannot delete all layers.||&OK"); return; } for (Layer* layer : selLayers) { api.removeLayer(layer); } } else { if (sprite->allLayersCount() == 1) { ui::Alert::show("Error<<You cannot delete the last layer.||&OK"); return; } Layer* layer = writer.layer(); layerName = layer->name(); api.removeLayer(layer); } transaction.commit(); } update_screen_for_document(document); StatusBar::instance()->invalidate(); if (!layerName.empty()) StatusBar::instance()->showTip(1000, "Layer '%s' removed", layerName.c_str()); else StatusBar::instance()->showTip(1000, "Layers removed"); }
void PixelsMovement::onRotationAlgorithmChange() { try { redrawExtraImage(); redrawCurrentMask(); updateDocumentMask(); update_screen_for_document(m_document); } catch (const std::exception& ex) { Console::showException(ex); } }
void AutocropSpriteCommand::onExecute(Context* context) { ContextWriter writer(context); Document* document(writer.document()); Sprite* sprite(writer.sprite()); { Transaction transaction(writer.context(), "Trim Sprite"); document->getApi(transaction).trimSprite(sprite); transaction.commit(); } document->generateMaskBoundaries(); update_screen_for_document(document); }
void PixelsMovement::rotate(double angle) { ContextWriter writer(m_reader, 1000); m_currentData.angle(m_currentData.angle() + PI * -angle / 180.0); m_document->setTransformation(m_currentData); redrawExtraImage(); redrawCurrentMask(); updateDocumentMask(); update_screen_for_document(m_document); }
void UndoCommand::onExecute(Context* context) { ContextWriter writer(context); Document* document(writer.document()); DocumentUndo* undo = document->getUndo(); Sprite* sprite = document->sprite(); if (context->settings()->undoGotoModified()) { SpritePosition spritePosition; SpritePosition currentPosition(writer.location()->layerIndex(), writer.location()->frame()); if (m_type == Undo) spritePosition = undo->getNextUndoSpritePosition(); else spritePosition = undo->getNextRedoSpritePosition(); if (spritePosition != currentPosition) { current_editor->setLayer(sprite->indexToLayer(spritePosition.layerIndex())); current_editor->setFrame(spritePosition.frameNumber()); // Draw the current layer/frame (which is not undone yet) so the // user can see the doUndo/doRedo effect. current_editor->drawSpriteClipped( gfx::Region(gfx::Rect(0, 0, sprite->width(), sprite->height()))); ui::dirty_display_flag = true; gui_feedback(); base::this_thread::sleep_for(0.01); } } StatusBar::instance() ->showTip(1000, "%s %s", (m_type == Undo ? "Undid": "Redid"), (m_type == Undo ? undo->getNextUndoLabel(): undo->getNextRedoLabel())); // Effectively undo/redo. if (m_type == Undo) undo->doUndo(); else undo->doRedo(); document->generateMaskBoundaries(); document->destroyExtraCel(); // Regenerate extras update_screen_for_document(document); set_current_palette(writer.palette(), false); }
void AutocropSpriteCommand::onExecute(Context* context) { ActiveDocumentWriter document(context); Sprite* sprite(document->getSprite()); { int bgcolor = color_utils::color_for_image(ColorBar::instance()->getBgColor(), sprite->getPixelFormat()); UndoTransaction undoTransaction(document, "Trim Sprite"); undoTransaction.trimSprite(bgcolor); undoTransaction.commit(); } document->generateMaskBoundaries(); update_screen_for_document(document); }
void BackgroundFromLayerCommand::onExecute(Context* context) { ContextWriter writer(context); Document* document(writer.document()); { Transaction transaction(writer.context(), "Background from Layer"); document->getApi(transaction).backgroundFromLayer( static_cast<LayerImage*>(writer.layer())); transaction.commit(); } update_screen_for_document(document); }
void FlattenLayersCommand::onExecute(Context* context) { ContextWriter writer(context); Document* document = writer.document(); Sprite* sprite = writer.sprite(); int bgcolor = color_utils::color_for_image(ColorBar::instance()->getBgColor(), sprite->getPixelFormat()); { UndoTransaction undoTransaction(writer.context(), "Flatten Layers"); document->getApi().flattenLayers(sprite, bgcolor); undoTransaction.commit(); } update_screen_for_document(writer.document()); }
void UndoCommand::onExecute(Context* context) { ActiveDocumentWriter document(context); app_get_statusbar() ->showTip(1000, "Undid %s", document->getUndoHistory()->getNextUndoLabel()); document->getUndoHistory()->doUndo(); document->generateMaskBoundaries(); document->destroyExtraCel(); // Regenerate extras update_screen_for_document(document); }
void LinkCelsCommand::onExecute(Context* context) { ContextWriter writer(context); Doc* document(writer.document()); bool nonEditableLayers = false; { auto site = context->activeSite(); if (!site.inTimeline()) return; Tx tx(writer.context(), friendlyName()); for (Layer* layer : site.selectedLayers()) { if (!layer->isImage()) continue; if (!layer->isEditableHierarchy()) { nonEditableLayers = true; continue; } LayerImage* layerImage = static_cast<LayerImage*>(layer); for (auto it=site.selectedFrames().begin(), end=site.selectedFrames().end(); it != end; ++it) { frame_t frame = *it; Cel* cel = layerImage->cel(frame); if (cel) { for (++it; it != end; ++it) { tx( new cmd::CopyCel( layerImage, cel->frame(), layerImage, *it, true)); // true = force links } break; } } } tx.commit(); } if (nonEditableLayers) StatusBar::instance()->showTip(1000, "There are locked layers"); update_screen_for_document(document); }
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()); } }