From fe39e0cd86bd4938172a1987f014224f9ce16bc5 Mon Sep 17 00:00:00 2001 From: Christian Kaiser Date: Wed, 23 Jul 2025 10:11:57 -0300 Subject: [PATCH] [lua] Add sprite.undoHistory --- src/app/script/site_class.cpp | 2 ++ src/app/script/sprite_class.cpp | 38 +++++++++++++++++++++++++++ tests/scripts/sprite.lua | 46 +++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) diff --git a/src/app/script/site_class.cpp b/src/app/script/site_class.cpp index 301bc5285..73934e36e 100644 --- a/src/app/script/site_class.cpp +++ b/src/app/script/site_class.cpp @@ -13,6 +13,8 @@ #include "app/console.h" #include "app/context.h" #include "app/context_observer.h" +#include "app/doc.h" +#include "app/doc_undo.h" #include "app/script/docobj.h" #include "app/script/engine.h" #include "app/script/luacpp.h" diff --git a/src/app/script/sprite_class.cpp b/src/app/script/sprite_class.cpp index 92fd395d5..892944acd 100644 --- a/src/app/script/sprite_class.cpp +++ b/src/app/script/sprite_class.cpp @@ -64,6 +64,7 @@ #include "doc/tag.h" #include "doc/tileset.h" #include "doc/tilesets.h" +#include "undo/undo_state.h" #include @@ -1029,6 +1030,42 @@ int Sprite_set_useLayerUuids(lua_State* L) return 0; } +int Sprite_get_undoHistory(lua_State* L) +{ + const auto* sprite = get_docobj(L, 1); + const auto* doc = static_cast(sprite->document()); + const auto* history = doc->undoHistory(); + + if (!history) { + lua_pushnil(L); + return 1; + } + + const undo::UndoState* currentState = history->currentState(); + const undo::UndoState* s = history->firstState(); + const bool canRedo = history->canRedo(); + bool pastCurrent = !currentState && canRedo; + + int undoSteps = 0; + int redoSteps = 0; + while (s) { + if (pastCurrent && canRedo) + redoSteps++; + else if (currentState || !canRedo) + undoSteps++; + + if (s == currentState || !currentState) + pastCurrent = true; + + s = s->next(); + } + + lua_newtable(L); + setfield_integer(L, "undoSteps", undoSteps); + setfield_integer(L, "redoSteps", redoSteps); + return 1; +} + const luaL_Reg Sprite_methods[] = { { "__eq", Sprite_eq }, { "resize", Sprite_resize }, @@ -1094,6 +1131,7 @@ const Property Sprite_properties[] = { { "events", Sprite_get_events, nullptr }, { "tileManagementPlugin", Sprite_get_tileManagementPlugin, Sprite_set_tileManagementPlugin }, { "useLayerUuids", Sprite_get_useLayerUuids, Sprite_set_useLayerUuids }, + { "undoHistory", Sprite_get_undoHistory, nullptr }, { nullptr, nullptr, nullptr } }; diff --git a/tests/scripts/sprite.lua b/tests/scripts/sprite.lua index ac964eada..3e288ec53 100644 --- a/tests/scripts/sprite.lua +++ b/tests/scripts/sprite.lua @@ -228,3 +228,49 @@ do c = app.open(fn) assert(c.tileManagementPlugin == nil) end + +-- Undo History +do + local sprite = Sprite(1, 1) + + assert(sprite.undoHistory.undoSteps == 0) + assert(sprite.undoHistory.redoSteps == 0) + + sprite:resize(10, 10) + + assert(sprite.undoHistory.undoSteps == 1) + assert(sprite.undoHistory.redoSteps == 0) + + sprite:resize(10, 15) + + assert(sprite.undoHistory.undoSteps == 2) + assert(sprite.undoHistory.redoSteps == 0) + + sprite:resize(10, 30) + + assert(sprite.undoHistory.undoSteps == 3) + assert(sprite.undoHistory.redoSteps == 0) + + app.undo() + assert(sprite.undoHistory.undoSteps == 2) + assert(sprite.undoHistory.redoSteps == 1) + + app.undo() + assert(sprite.undoHistory.undoSteps == 1) + assert(sprite.undoHistory.redoSteps == 2) + + app.redo() + assert(sprite.undoHistory.undoSteps == 2) + assert(sprite.undoHistory.redoSteps == 1) + + app.undo() + app.undo() + + assert(sprite.undoHistory.undoSteps == 0) + assert(sprite.undoHistory.redoSteps == 3) + + sprite:resize(10, 30) + + assert(sprite.undoHistory.undoSteps == 1) + assert(sprite.undoHistory.redoSteps == 0) +end