void UndoCommand::onExecute(Context* context) { ContextWriter writer(context); Document* document(writer.document()); DocumentUndo* undo = document->undoHistory(); Sprite* sprite = document->sprite(); SpritePosition spritePosition; const bool gotoModified = Preferences::instance().undo.gotoModified(); if (gotoModified) { SpritePosition currentPosition(writer.site()->layerIndex(), writer.site()->frame()); if (m_type == Undo) spritePosition = undo->nextUndoSpritePosition(); else spritePosition = undo->nextRedoSpritePosition(); if (spritePosition != currentPosition) { current_editor->setLayer(sprite->indexToLayer(spritePosition.layerIndex())); current_editor->setFrame(spritePosition.frame()); // 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()))); current_editor->manager()->flipDisplay(); base::this_thread::sleep_for(0.01); } } StatusBar* statusbar = StatusBar::instance(); if (statusbar) statusbar->showTip(1000, "%s %s", (m_type == Undo ? "Undid": "Redid"), (m_type == Undo ? undo->nextUndoLabel().c_str(): undo->nextRedoLabel().c_str())); // Effectively undo/redo. if (m_type == Undo) undo->undo(); else undo->redo(); // After redo/undo, we retry to change the current SpritePosition // (because new frames/layers could be added, positions that we // weren't able to reach before the undo). if (gotoModified) { SpritePosition currentPosition( writer.site()->layerIndex(), writer.site()->frame()); if (spritePosition != currentPosition) { current_editor->setLayer(sprite->indexToLayer(spritePosition.layerIndex())); current_editor->setFrame(spritePosition.frame()); } } document->generateMaskBoundaries(); document->setExtraCel(ExtraCelRef(nullptr)); update_screen_for_document(document); set_current_palette(writer.palette(), false); }