[lua] Add remaptileset event for sprites

This commit is contained in:
David Capello 2022-12-27 14:11:05 -03:00
parent d683aaf437
commit 25a4e67aaa
5 changed files with 65 additions and 8 deletions

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2019 Igara Studio S.A.
// Copyright (C) 2019-2022 Igara Studio S.A.
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -10,9 +10,10 @@
#include "app/cmd/remap_tilemaps.h"
#include "app/doc.h"
#include "app/doc_event.h"
#include "doc/cel.h"
#include "doc/cels_range.h"
#include "doc/image.h"
#include "doc/layer.h"
#include "doc/layer_tilemap.h"
#include "doc/remap.h"
@ -34,19 +35,29 @@ RemapTilemaps::RemapTilemaps(Tileset* tileset,
void RemapTilemaps::onExecute()
{
Tileset* tileset = this->tileset();
Sprite* spr = tileset->sprite();
spr->remapTilemaps(tileset, m_remap);
remapTileset(tileset, m_remap);
incrementVersions(tileset);
}
void RemapTilemaps::onUndo()
{
Tileset* tileset = this->tileset();
Sprite* spr = tileset->sprite();
spr->remapTilemaps(tileset, m_remap.invert());
remapTileset(tileset, m_remap.invert());
incrementVersions(tileset);
}
void RemapTilemaps::remapTileset(Tileset* tileset, const Remap& remap)
{
Sprite* spr = tileset->sprite();
spr->remapTilemaps(tileset, remap);
Doc* doc = static_cast<Doc*>(spr->document());
DocEvent ev(doc);
ev.sprite(spr);
ev.tileset(tileset);
doc->notify_observers<DocEvent&, const Remap&>(&DocObserver::onRemapTileset, ev, remap);
}
void RemapTilemaps::incrementVersions(Tileset* tileset)
{
Sprite* spr = tileset->sprite();

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2019 Igara Studio S.A.
// Copyright (C) 2019-2022 Igara Studio S.A.
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -30,6 +30,7 @@ namespace cmd {
}
private:
void remapTileset(Tileset* tileset, const Remap& remap);
void incrementVersions(Tileset* tileset);
Remap m_remap;

View File

@ -9,6 +9,10 @@
#define APP_DOC_OBSERVER_H_INCLUDED
#pragma once
namespace doc {
class Remap;
}
namespace app {
class Doc;
class DocEvent;
@ -92,6 +96,9 @@ namespace app {
// The collapsed/expanded flag of a specific layer changed.
virtual void onLayerCollapsedChanged(DocEvent& ev) { }
// The tileset was remapped (e.g. when tiles are re-ordered).
virtual void onRemapTileset(DocEvent& ev, const doc::Remap& remap) { }
};
} // namespace app

View File

@ -12,6 +12,7 @@
#include "app/context.h"
#include "app/context_observer.h"
#include "app/doc.h"
#include "app/doc_event.h"
#include "app/doc_undo.h"
#include "app/doc_undo_observer.h"
#include "app/pref/preferences.h"
@ -209,7 +210,12 @@ class SpriteEvents : public Events
, public DocUndoObserver
, public DocObserver {
public:
enum : EventType { Unknown = -1, Change, FilenameChange };
enum : EventType {
Unknown = -1,
Change,
FilenameChange,
RemapTileset,
};
SpriteEvents(const Sprite* sprite)
: m_spriteId(sprite->id()) {
@ -235,6 +241,8 @@ public:
return Change;
else if (std::strcmp(eventName, "filenamechange") == 0)
return FilenameChange;
else if (std::strcmp(eventName, "remaptileset") == 0)
return RemapTileset;
else
return Unknown;
}
@ -253,6 +261,12 @@ public:
call(FilenameChange);
}
void onRemapTileset(DocEvent& ev, const doc::Remap& remap) override {
const bool fromUndo = (ev.document()->transaction() == nullptr);
call(RemapTileset, { { "remap", std::any(&remap) },
{ "fromUndo", fromUndo } });
}
// DocUndoObserver impl
void onAddUndoState(DocUndo* history) override {
call(Change);

View File

@ -13,6 +13,7 @@
#include "app/pref/preferences.h"
#include "app/script/engine.h"
#include "app/script/luacpp.h"
#include "doc/remap.h"
#include <any>
@ -76,6 +77,27 @@ std::string get_value_from_lua(lua_State* L, int index) {
return std::string();
}
// ----------------------------------------------------------------------
// doc::Remap
template<>
void push_value_to_lua(lua_State* L, const doc::Remap& value) {
lua_newtable(L);
for (int i=0; i<value.size(); ++i) {
lua_pushinteger(L, value[i]);
// This will be a weird Lua table where the base index start at 0,
// anyway the tile=0 cannot be remapped, so it doesn't contain
// useful information anyway. The idea here is that the user can
// do something like this:
//
// newTileIndex = remap[oldTileIndex]
//
// And it should just work.
lua_seti(L, -2, i);
}
}
// ----------------------------------------------------------------------
// std::any
@ -89,6 +111,8 @@ void push_value_to_lua(lua_State* L, const std::any& value) {
push_value_to_lua(L, *v);
else if (const std::string* v = std::any_cast<std::string>(&value))
push_value_to_lua(L, *v);
else if (const doc::Remap* v = std::any_cast<const doc::Remap*>(value))
push_value_to_lua(L, *v);
else {
ASSERT(false);
throw std::runtime_error("Cannot convert type inside std::any");