mirror of
https://github.com/aseprite/aseprite.git
synced 2024-10-04 13:59:46 +00:00
[lua] Add Tileset:tile(tileIndex) API to get tile image/data/properties (fix #3653)
This should replace the old Tileset:getTile(tileIndex) which returns only the image.
This commit is contained in:
parent
6534d37b40
commit
81b2507bb6
@ -206,6 +206,7 @@ if(ENABLE_SCRIPTING)
|
||||
script/sprites_class.cpp
|
||||
script/tag_class.cpp
|
||||
script/tags_class.cpp
|
||||
script/tile_class.cpp
|
||||
script/tileset_class.cpp
|
||||
script/tilesets_class.cpp
|
||||
script/tool_class.cpp
|
||||
@ -523,6 +524,9 @@ add_library(app-lib
|
||||
cmd/set_tag_name.cpp
|
||||
cmd/set_tag_range.cpp
|
||||
cmd/set_tag_repeat.cpp
|
||||
cmd/set_tile_data.cpp
|
||||
cmd/set_tile_data_properties.cpp
|
||||
cmd/set_tile_data_property.cpp
|
||||
cmd/set_tileset_base_index.cpp
|
||||
cmd/set_tileset_name.cpp
|
||||
cmd/set_total_frames.cpp
|
||||
|
43
src/app/cmd/set_tile_data.cpp
Normal file
43
src/app/cmd/set_tile_data.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2023 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/cmd/set_tile_data.h"
|
||||
|
||||
#include "doc/tileset.h"
|
||||
|
||||
namespace app {
|
||||
namespace cmd {
|
||||
|
||||
SetTileData::SetTileData(doc::Tileset* ts,
|
||||
doc::tile_index ti,
|
||||
const doc::UserData& ud)
|
||||
: WithTileset(ts)
|
||||
, m_ti(ti)
|
||||
, m_oldUserData(ts->getTileData(ti))
|
||||
, m_newUserData(ud)
|
||||
{
|
||||
}
|
||||
|
||||
void SetTileData::onExecute()
|
||||
{
|
||||
auto ts = tileset();
|
||||
ts->setTileData(m_ti, m_newUserData);
|
||||
ts->incrementVersion();
|
||||
}
|
||||
|
||||
void SetTileData::onUndo()
|
||||
{
|
||||
auto ts = tileset();
|
||||
ts->setTileData(m_ti, m_oldUserData);
|
||||
ts->incrementVersion();
|
||||
}
|
||||
|
||||
} // namespace cmd
|
||||
} // namespace app
|
42
src/app/cmd/set_tile_data.h
Normal file
42
src/app/cmd/set_tile_data.h
Normal file
@ -0,0 +1,42 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2023 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifndef APP_CMD_SET_TILE_DATA_H_INCLUDED
|
||||
#define APP_CMD_SET_TILE_DATA_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/cmd.h"
|
||||
#include "app/cmd/with_tileset.h"
|
||||
#include "doc/tile.h"
|
||||
#include "doc/user_data.h"
|
||||
|
||||
namespace app {
|
||||
namespace cmd {
|
||||
|
||||
class SetTileData : public Cmd,
|
||||
public WithTileset {
|
||||
public:
|
||||
SetTileData(doc::Tileset* ts,
|
||||
doc::tile_index ti,
|
||||
const doc::UserData& ud);
|
||||
|
||||
protected:
|
||||
void onExecute() override;
|
||||
void onUndo() override;
|
||||
size_t onMemSize() const override {
|
||||
return sizeof(*this); // TODO + properties size
|
||||
}
|
||||
|
||||
private:
|
||||
doc::tile_index m_ti;
|
||||
doc::UserData m_oldUserData;
|
||||
doc::UserData m_newUserData;
|
||||
};
|
||||
|
||||
} // namespace cmd
|
||||
} // namespace app
|
||||
|
||||
#endif
|
46
src/app/cmd/set_tile_data_properties.cpp
Normal file
46
src/app/cmd/set_tile_data_properties.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2023 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/cmd/set_tile_data_properties.h"
|
||||
|
||||
#include "doc/tileset.h"
|
||||
|
||||
namespace app {
|
||||
namespace cmd {
|
||||
|
||||
SetTileDataProperties::SetTileDataProperties(
|
||||
doc::Tileset* ts,
|
||||
doc::tile_index ti,
|
||||
const std::string& group,
|
||||
doc::UserData::Properties&& newProperties)
|
||||
: WithTileset(ts)
|
||||
, m_ti(ti)
|
||||
, m_group(group)
|
||||
, m_oldProperties(ts->getTileData(ti).properties(group))
|
||||
, m_newProperties(std::move(newProperties))
|
||||
{
|
||||
}
|
||||
|
||||
void SetTileDataProperties::onExecute()
|
||||
{
|
||||
auto ts = tileset();
|
||||
ts->getTileData(m_ti).properties(m_group) = m_newProperties;
|
||||
ts->incrementVersion();
|
||||
}
|
||||
|
||||
void SetTileDataProperties::onUndo()
|
||||
{
|
||||
auto ts = tileset();
|
||||
ts->getTileData(m_ti).properties(m_group) = m_oldProperties;
|
||||
ts->incrementVersion();
|
||||
}
|
||||
|
||||
} // namespace cmd
|
||||
} // namespace app
|
45
src/app/cmd/set_tile_data_properties.h
Normal file
45
src/app/cmd/set_tile_data_properties.h
Normal file
@ -0,0 +1,45 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2023 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifndef APP_CMD_SET_TILE_DATA_PROPERTIES_H_INCLUDED
|
||||
#define APP_CMD_SET_TILE_DATA_PROPERTIES_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/cmd.h"
|
||||
#include "app/cmd/with_tileset.h"
|
||||
#include "doc/tile.h"
|
||||
#include "doc/user_data.h"
|
||||
|
||||
namespace app {
|
||||
namespace cmd {
|
||||
|
||||
class SetTileDataProperties : public Cmd,
|
||||
public WithTileset {
|
||||
public:
|
||||
SetTileDataProperties(
|
||||
doc::Tileset* ts,
|
||||
doc::tile_index ti,
|
||||
const std::string& group,
|
||||
doc::UserData::Properties&& newProperties);
|
||||
|
||||
protected:
|
||||
void onExecute() override;
|
||||
void onUndo() override;
|
||||
size_t onMemSize() const override {
|
||||
return sizeof(*this); // TODO + properties size
|
||||
}
|
||||
|
||||
private:
|
||||
doc::tile_index m_ti;
|
||||
std::string m_group;
|
||||
doc::UserData::Properties m_oldProperties;
|
||||
doc::UserData::Properties m_newProperties;
|
||||
};
|
||||
|
||||
} // namespace cmd
|
||||
} // namespace app
|
||||
|
||||
#endif
|
68
src/app/cmd/set_tile_data_property.cpp
Normal file
68
src/app/cmd/set_tile_data_property.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2023 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/cmd/set_tile_data_property.h"
|
||||
|
||||
#include "doc/tileset.h"
|
||||
|
||||
namespace app {
|
||||
namespace cmd {
|
||||
|
||||
SetTileDataProperty::SetTileDataProperty(
|
||||
doc::Tileset* ts,
|
||||
doc::tile_index ti,
|
||||
const std::string& group,
|
||||
const std::string& field,
|
||||
doc::UserData::Variant&& newValue)
|
||||
: WithTileset(ts)
|
||||
, m_ti(ti)
|
||||
, m_group(group)
|
||||
, m_field(field)
|
||||
, m_oldValue(ts->getTileData(m_ti).properties(m_group)[m_field])
|
||||
, m_newValue(std::move(newValue))
|
||||
{
|
||||
}
|
||||
|
||||
void SetTileDataProperty::onExecute()
|
||||
{
|
||||
auto ts = tileset();
|
||||
auto& properties = ts->getTileData(m_ti).properties(m_group);
|
||||
|
||||
if (m_newValue.type() == USER_DATA_PROPERTY_TYPE_NULLPTR) {
|
||||
auto it = properties.find(m_field);
|
||||
if (it != properties.end())
|
||||
properties.erase(it);
|
||||
}
|
||||
else {
|
||||
properties[m_field] = m_newValue;
|
||||
}
|
||||
|
||||
ts->incrementVersion();
|
||||
}
|
||||
|
||||
void SetTileDataProperty::onUndo()
|
||||
{
|
||||
auto ts = tileset();
|
||||
auto& properties = ts->getTileData(m_ti).properties(m_group);
|
||||
|
||||
if (m_oldValue.type() == USER_DATA_PROPERTY_TYPE_NULLPTR) {
|
||||
auto it = properties.find(m_field);
|
||||
if (it != properties.end())
|
||||
properties.erase(it);
|
||||
}
|
||||
else {
|
||||
properties[m_field] = m_oldValue;
|
||||
}
|
||||
|
||||
ts->incrementVersion();
|
||||
}
|
||||
|
||||
} // namespace cmd
|
||||
} // namespace app
|
47
src/app/cmd/set_tile_data_property.h
Normal file
47
src/app/cmd/set_tile_data_property.h
Normal file
@ -0,0 +1,47 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2023 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifndef APP_CMD_SET_TILE_DATA_PROPERTY_H_INCLUDED
|
||||
#define APP_CMD_SET_TILE_DATA_PROPERTY_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/cmd.h"
|
||||
#include "app/cmd/with_tileset.h"
|
||||
#include "doc/tile.h"
|
||||
#include "doc/user_data.h"
|
||||
|
||||
namespace app {
|
||||
namespace cmd {
|
||||
|
||||
class SetTileDataProperty : public Cmd,
|
||||
public WithTileset {
|
||||
public:
|
||||
SetTileDataProperty(
|
||||
doc::Tileset* ts,
|
||||
doc::tile_index ti,
|
||||
const std::string& group,
|
||||
const std::string& field,
|
||||
doc::UserData::Variant&& newValue);
|
||||
|
||||
protected:
|
||||
void onExecute() override;
|
||||
void onUndo() override;
|
||||
size_t onMemSize() const override {
|
||||
return sizeof(*this); // TODO + variant size
|
||||
}
|
||||
|
||||
private:
|
||||
doc::tile_index m_ti;
|
||||
std::string m_group;
|
||||
std::string m_field;
|
||||
doc::UserData::Variant m_oldValue;
|
||||
doc::UserData::Variant m_newValue;
|
||||
};
|
||||
|
||||
} // namespace cmd
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2023 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -189,6 +189,7 @@ void register_sprites_class(lua_State* L);
|
||||
void register_tag_class(lua_State* L);
|
||||
void register_tags_class(lua_State* L);
|
||||
void register_theme_classes(lua_State* L);
|
||||
void register_tile_class(lua_State* L);
|
||||
void register_tileset_class(lua_State* L);
|
||||
void register_tilesets_class(lua_State* L);
|
||||
void register_tool_class(lua_State* L);
|
||||
@ -468,6 +469,7 @@ Engine::Engine()
|
||||
register_tag_class(L);
|
||||
register_tags_class(L);
|
||||
register_theme_classes(L);
|
||||
register_tile_class(L);
|
||||
register_tileset_class(L);
|
||||
register_tilesets_class(L);
|
||||
register_tool_class(L);
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "doc/frame.h"
|
||||
#include "doc/object_ids.h"
|
||||
#include "doc/pixel_format.h"
|
||||
#include "doc/tile.h"
|
||||
#include "gfx/fwd.h"
|
||||
|
||||
#include <cstdio>
|
||||
@ -163,6 +164,8 @@ namespace app {
|
||||
void push_sprite_slices(lua_State* L, doc::Sprite* sprite);
|
||||
void push_sprite_tags(lua_State* L, doc::Sprite* sprite);
|
||||
void push_sprites(lua_State* L);
|
||||
void push_tile(lua_State* L, const doc::Tileset* tileset, doc::tile_index ti);
|
||||
void push_tile_properties(lua_State* L, const doc::Tileset* tileset, doc::tile_index ti, const std::string& extID);
|
||||
void push_tileset(lua_State* L, const doc::Tileset* tileset);
|
||||
void push_tileset_image(lua_State* L, doc::Tileset* tileset, doc::Image* image);
|
||||
void push_tilesets(lua_State* L, doc::Tilesets* tilesets);
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/cmd/set_tile_data_properties.h"
|
||||
#include "app/cmd/set_tile_data_property.h"
|
||||
#include "app/cmd/set_user_data_properties.h"
|
||||
#include "app/cmd/set_user_data_property.h"
|
||||
#include "app/script/docobj.h"
|
||||
@ -15,6 +17,7 @@
|
||||
#include "app/script/luacpp.h"
|
||||
#include "app/script/values.h"
|
||||
#include "app/tx.h"
|
||||
#include "doc/tileset.h"
|
||||
#include "doc/with_user_data.h"
|
||||
|
||||
#include <cstring>
|
||||
@ -25,14 +28,58 @@ namespace script {
|
||||
namespace {
|
||||
|
||||
struct Properties {
|
||||
// WithUserData ID or tileset ID
|
||||
doc::ObjectId id = 0;
|
||||
// If notile, it's the properties of a WithUserData, in other case,
|
||||
// it's the user data of this specific tile.
|
||||
doc::tile_index ti = doc::notile;
|
||||
std::string extID;
|
||||
|
||||
Properties(doc::ObjectId id,
|
||||
Properties(const doc::WithUserData* wud,
|
||||
const std::string& extID)
|
||||
: id(id)
|
||||
: id(wud->id())
|
||||
, extID(extID) {
|
||||
}
|
||||
|
||||
Properties(const doc::Tileset* ts,
|
||||
const doc::tile_index ti,
|
||||
const std::string& extID)
|
||||
: id(ts->id())
|
||||
, ti(ti)
|
||||
, extID(extID) {
|
||||
}
|
||||
|
||||
Properties(const Properties& copy,
|
||||
const std::string& extID)
|
||||
: id(copy.id)
|
||||
, ti(copy.ti)
|
||||
, extID(extID) {
|
||||
}
|
||||
|
||||
doc::WithUserData* object(lua_State* L) {
|
||||
auto obj = static_cast<doc::WithUserData*>(doc::get_object(id));
|
||||
if (!obj) {
|
||||
// luaL_error never returns
|
||||
luaL_error(L, "the object with these properties was destroyed");
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
doc::UserData::Properties& properties(lua_State* L, doc::WithUserData* obj = nullptr) {
|
||||
if (!obj)
|
||||
obj = object(L);
|
||||
if (ti == doc::notile) {
|
||||
return obj->userData().properties(extID);
|
||||
}
|
||||
else {
|
||||
ASSERT(obj->type() == doc::ObjectType::Tileset);
|
||||
return
|
||||
const_cast<doc::UserData*>(
|
||||
&static_cast<doc::Tileset*>(obj)->getTileData(ti))
|
||||
->properties(extID);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
using PropertiesIterator = doc::UserData::Properties::iterator;
|
||||
@ -40,11 +87,7 @@ using PropertiesIterator = doc::UserData::Properties::iterator;
|
||||
int Properties_len(lua_State* L)
|
||||
{
|
||||
auto propObj = get_obj<Properties>(L, 1);
|
||||
auto obj = static_cast<doc::WithUserData*>(get_object(propObj->id));
|
||||
if (!obj)
|
||||
return luaL_error(L, "the object with these properties was destroyed");
|
||||
|
||||
auto& properties = obj->userData().properties(propObj->extID);
|
||||
auto& properties = propObj->properties(L);
|
||||
lua_pushinteger(L, properties.size());
|
||||
return 1;
|
||||
}
|
||||
@ -56,11 +99,7 @@ int Properties_index(lua_State* L)
|
||||
if (!field)
|
||||
return luaL_error(L, "field in 'properties.field' must be a string");
|
||||
|
||||
auto obj = static_cast<doc::WithUserData*>(get_object(propObj->id));
|
||||
if (!obj)
|
||||
return luaL_error(L, "the object with these properties was destroyed");
|
||||
|
||||
auto& properties = obj->userData().properties(propObj->extID);
|
||||
auto& properties = propObj->properties(L);
|
||||
auto it = properties.find(field);
|
||||
if (it != properties.end()) {
|
||||
push_value_to_lua(L, (*it).second);
|
||||
@ -82,15 +121,22 @@ int Properties_newindex(lua_State* L)
|
||||
if (!obj)
|
||||
return luaL_error(L, "the object with these properties was destroyed");
|
||||
|
||||
auto& properties = obj->userData().properties(propObj->extID);
|
||||
auto& properties = propObj->properties(L, obj);
|
||||
auto newValue = get_value_from_lua<doc::UserData::Variant>(L, 3);
|
||||
|
||||
// TODO add Object::sprite() member function
|
||||
//if (obj->sprite()) {
|
||||
if (App::instance()->context()->activeDocument()) {
|
||||
Tx tx;
|
||||
tx(new cmd::SetUserDataProperty(obj, propObj->extID, field,
|
||||
std::move(newValue)));
|
||||
if (propObj->ti != doc::notile) {
|
||||
tx(new cmd::SetTileDataProperty(static_cast<doc::Tileset*>(obj),
|
||||
propObj->ti, propObj->extID, field,
|
||||
std::move(newValue)));
|
||||
}
|
||||
else {
|
||||
tx(new cmd::SetUserDataProperty(obj, propObj->extID, field,
|
||||
std::move(newValue)));
|
||||
}
|
||||
tx.commit();
|
||||
}
|
||||
else {
|
||||
@ -121,7 +167,13 @@ int Properties_call(lua_State* L)
|
||||
//if (obj->sprite()) {
|
||||
if (App::instance()->context()->activeDocument()) {
|
||||
Tx tx;
|
||||
tx(new cmd::SetUserDataProperties(obj, extID, std::move(newProperties)));
|
||||
if (propObj->ti != doc::notile) {
|
||||
tx(new cmd::SetTileDataProperties(static_cast<doc::Tileset*>(obj),
|
||||
propObj->ti, extID, std::move(newProperties)));
|
||||
}
|
||||
else {
|
||||
tx(new cmd::SetUserDataProperties(obj, extID, std::move(newProperties)));
|
||||
}
|
||||
tx.commit();
|
||||
}
|
||||
else {
|
||||
@ -130,18 +182,14 @@ int Properties_call(lua_State* L)
|
||||
}
|
||||
}
|
||||
|
||||
push_new<Properties>(L, propObj->id, extID);
|
||||
push_new<Properties>(L, *propObj, extID);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Properties_pairs_next(lua_State* L)
|
||||
{
|
||||
auto propObj = get_obj<Properties>(L, 1);
|
||||
auto obj = static_cast<doc::WithUserData*>(get_object(propObj->id));
|
||||
if (!obj)
|
||||
return luaL_error(L, "the object with these properties was destroyed");
|
||||
|
||||
auto& properties = obj->userData().properties(propObj->extID);
|
||||
auto& properties = propObj->properties(L);
|
||||
auto& it = *get_obj<PropertiesIterator>(L, lua_upvalueindex(1));
|
||||
if (it == properties.end())
|
||||
return 0;
|
||||
@ -158,7 +206,7 @@ int Properties_pairs(lua_State* L)
|
||||
if (!obj)
|
||||
return luaL_error(L, "the object with these properties was destroyed");
|
||||
|
||||
auto& properties = obj->userData().properties(propObj->extID);
|
||||
auto& properties = propObj->properties(L);
|
||||
|
||||
push_obj(L, properties.begin());
|
||||
lua_pushcclosure(L, Properties_pairs_next, 1);
|
||||
@ -198,10 +246,18 @@ void register_properties_class(lua_State* L)
|
||||
}
|
||||
|
||||
void push_properties(lua_State* L,
|
||||
doc::WithUserData* userData,
|
||||
doc::WithUserData* wud,
|
||||
const std::string& extID)
|
||||
{
|
||||
push_new<Properties>(L, userData->id(), extID);
|
||||
push_new<Properties>(L, wud, extID);
|
||||
}
|
||||
|
||||
void push_tile_properties(lua_State* L,
|
||||
const doc::Tileset* ts,
|
||||
doc::tile_index ti,
|
||||
const std::string& extID)
|
||||
{
|
||||
push_new<Properties>(L, ts, ti, extID);
|
||||
}
|
||||
|
||||
} // namespace script
|
||||
|
191
src/app/script/tile_class.cpp
Normal file
191
src/app/script/tile_class.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2023 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/cmd/set_tile_data.h"
|
||||
#include "app/cmd/set_tile_data_properties.h"
|
||||
#include "app/script/docobj.h"
|
||||
#include "app/script/engine.h"
|
||||
#include "app/script/luacpp.h"
|
||||
#include "app/script/userdata.h"
|
||||
#include "doc/tileset.h"
|
||||
|
||||
namespace app {
|
||||
namespace script {
|
||||
|
||||
using namespace doc;
|
||||
|
||||
namespace {
|
||||
|
||||
struct Tile {
|
||||
ObjectId id;
|
||||
tile_index ti;
|
||||
Tile(const Tileset* ts,
|
||||
const tile_index ti)
|
||||
: id(ts->id())
|
||||
, ti(ti) {
|
||||
}
|
||||
};
|
||||
|
||||
int Tile_get_image(lua_State* L)
|
||||
{
|
||||
auto tile = get_obj<Tile>(L, 1);
|
||||
auto ts = doc::get<Tileset>(tile->id);
|
||||
if (!ts)
|
||||
return 0;
|
||||
|
||||
ImageRef image = ts->get(tile->ti);
|
||||
if (image)
|
||||
push_tileset_image(L, ts, image.get());
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Tile_get_data(lua_State* L)
|
||||
{
|
||||
auto tile = get_obj<Tile>(L, 1);
|
||||
auto ts = doc::get<Tileset>(tile->id);
|
||||
if (!ts)
|
||||
return 0;
|
||||
|
||||
auto& ud = ts->getTileData(tile->ti);
|
||||
lua_pushstring(L, ud.text().c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Tile_get_color(lua_State* L)
|
||||
{
|
||||
auto tile = get_obj<Tile>(L, 1);
|
||||
auto ts = doc::get<Tileset>(tile->id);
|
||||
if (!ts)
|
||||
return 0;
|
||||
|
||||
auto& ud = ts->getTileData(tile->ti);
|
||||
doc::color_t docColor = ud.color();
|
||||
app::Color appColor = app::Color::fromRgb(doc::rgba_getr(docColor),
|
||||
doc::rgba_getg(docColor),
|
||||
doc::rgba_getb(docColor),
|
||||
doc::rgba_geta(docColor));
|
||||
if (appColor.getAlpha() == 0)
|
||||
appColor = app::Color::fromMask();
|
||||
push_obj<app::Color>(L, appColor);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Tile_get_properties(lua_State* L)
|
||||
{
|
||||
auto tile = get_obj<Tile>(L, 1);
|
||||
auto ts = doc::get<Tileset>(tile->id);
|
||||
if (!ts)
|
||||
return 0;
|
||||
|
||||
push_tile_properties(L, ts, tile->ti, std::string());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Tile_set_data(lua_State* L)
|
||||
{
|
||||
auto tile = get_obj<Tile>(L, 1);
|
||||
auto ts = doc::get<Tileset>(tile->id);
|
||||
if (!ts)
|
||||
return 0;
|
||||
|
||||
const char* text = lua_tostring(L, 2);
|
||||
if (!text)
|
||||
text = "";
|
||||
|
||||
doc::UserData ud = ts->getTileData(tile->ti);
|
||||
ud.setText(text);
|
||||
|
||||
if (ts->sprite()) { // TODO use transaction in this sprite
|
||||
Tx tx;
|
||||
tx(new cmd::SetTileData(ts, tile->ti, ud));
|
||||
tx.commit();
|
||||
}
|
||||
else {
|
||||
ts->setTileData(tile->ti, ud);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Tile_set_color(lua_State* L)
|
||||
{
|
||||
auto tile = get_obj<Tile>(L, 1);
|
||||
auto ts = doc::get<Tileset>(tile->id);
|
||||
if (!ts)
|
||||
return 0;
|
||||
|
||||
doc::color_t docColor = convert_args_into_pixel_color(L, 2, doc::IMAGE_RGB);
|
||||
|
||||
doc::UserData ud = ts->getTileData(tile->ti);
|
||||
ud.setColor(docColor);
|
||||
|
||||
if (ts->sprite()) { // TODO use transaction in this sprite
|
||||
Tx tx;
|
||||
tx(new cmd::SetTileData(ts, tile->ti, ud));
|
||||
tx.commit();
|
||||
}
|
||||
else {
|
||||
ts->setTileData(tile->ti, ud);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Tile_set_properties(lua_State* L)
|
||||
{
|
||||
auto tile = get_obj<Tile>(L, 1);
|
||||
auto ts = doc::get<Tileset>(tile->id);
|
||||
if (!ts)
|
||||
return 0;
|
||||
|
||||
auto newProperties = get_value_from_lua<doc::UserData::Properties>(L, 2);
|
||||
if (ts->sprite()) {
|
||||
Tx tx;
|
||||
tx(new cmd::SetTileDataProperties(ts, tile->ti,
|
||||
std::string(),
|
||||
std::move(newProperties)));
|
||||
tx.commit();
|
||||
}
|
||||
else {
|
||||
auto& properties = ts->getTileData(tile->ti).properties();
|
||||
properties = std::move(newProperties);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const luaL_Reg Tile_methods[] = {
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
||||
const Property Tile_properties[] = {
|
||||
{ "image", Tile_get_image, nullptr }, // TODO Tile_set_image
|
||||
{ "data", Tile_get_data, Tile_set_data },
|
||||
{ "color", Tile_get_color, Tile_set_color },
|
||||
{ "properties", Tile_get_properties, Tile_set_properties },
|
||||
{ nullptr, nullptr, nullptr }
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
DEF_MTNAME(Tile);
|
||||
|
||||
void register_tile_class(lua_State* L)
|
||||
{
|
||||
REG_CLASS(L, Tile);
|
||||
REG_CLASS_PROPERTIES(L, Tile);
|
||||
}
|
||||
|
||||
void push_tile(lua_State* L, const Tileset* ts, tile_index ti)
|
||||
{
|
||||
push_new<Tile>(L, ts, ti);
|
||||
}
|
||||
|
||||
} // namespace script
|
||||
} // namespace app
|
@ -48,6 +48,17 @@ int Tileset_getTile(lua_State* L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Tileset_tile(lua_State* L)
|
||||
{
|
||||
auto tileset = get_docobj<Tileset>(L, 1);
|
||||
tile_index ti = lua_tointeger(L, 2);
|
||||
if (ti >= 0 && ti < tileset->size())
|
||||
push_tile(L, tileset, ti);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Tileset_get_name(lua_State* L)
|
||||
{
|
||||
auto tileset = get_docobj<Tileset>(L, 1);
|
||||
@ -89,8 +100,7 @@ const luaL_Reg Tileset_methods[] = {
|
||||
{ "__eq", Tileset_eq },
|
||||
{ "__len", Tileset_len },
|
||||
{ "getTile", Tileset_getTile },
|
||||
// TODO
|
||||
// { "setTile", Tileset_setTile },
|
||||
{ "tile", Tileset_tile },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (c) 2019-2022 Igara Studio S.A.
|
||||
// Copyright (c) 2019-2023 Igara Studio S.A.
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -20,6 +20,9 @@
|
||||
|
||||
namespace doc {
|
||||
|
||||
// static
|
||||
UserData Tileset::kNoUserData;
|
||||
|
||||
Tileset::Tileset(Sprite* sprite,
|
||||
const Grid& grid,
|
||||
const tileset_index ntiles)
|
||||
@ -131,7 +134,8 @@ void Tileset::remap(const Remap& remap)
|
||||
void Tileset::setTileData(const tile_index ti,
|
||||
const UserData& userData)
|
||||
{
|
||||
m_datas[ti] = userData;
|
||||
if (ti >= 0 && ti < size())
|
||||
m_datas[ti] = userData;
|
||||
}
|
||||
|
||||
void Tileset::set(const tile_index ti,
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (c) 2019-2022 Igara Studio S.A.
|
||||
// Copyright (c) 2019-2023 Igara Studio S.A.
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -24,6 +24,7 @@ namespace doc {
|
||||
class Sprite;
|
||||
|
||||
class Tileset : public WithUserData {
|
||||
static UserData kNoUserData;
|
||||
public:
|
||||
typedef std::vector<ImageRef> Tiles;
|
||||
typedef std::vector<UserData> Datas;
|
||||
@ -69,11 +70,11 @@ namespace doc {
|
||||
void set(const tile_index ti,
|
||||
const ImageRef& image);
|
||||
|
||||
UserData getTileData(const tile_index ti) const {
|
||||
UserData& getTileData(const tile_index ti) const {
|
||||
if (ti >= 0 && ti < size())
|
||||
return m_datas[ti];
|
||||
return const_cast<UserData&>(m_datas[ti]);
|
||||
else
|
||||
return UserData();
|
||||
return kNoUserData;
|
||||
}
|
||||
void setTileData(const tile_index ti,
|
||||
const UserData& userData);
|
||||
|
85
tests/scripts/tiledata.lua
Normal file
85
tests/scripts/tiledata.lua
Normal file
@ -0,0 +1,85 @@
|
||||
-- Copyright (C) 2023 Igara Studio S.A.
|
||||
--
|
||||
-- This file is released under the terms of the MIT license.
|
||||
-- Read LICENSE.txt for more information.
|
||||
|
||||
do
|
||||
local spr = Sprite(4, 4, ColorMode.INDEXED)
|
||||
spr.gridBounds = Rectangle(0, 0, 2, 2)
|
||||
app.command.NewLayer{ tilemap=true }
|
||||
local tilemap = spr.layers[2]
|
||||
local tileset = tilemap.tileset
|
||||
|
||||
app.useTool{
|
||||
tool='pencil',
|
||||
color=1,
|
||||
layer=tilemap,
|
||||
tilesetMode=TilesetMode.STACK,
|
||||
points={ Point(0, 0), Point(4, 3) }}
|
||||
assert(#tileset == 3)
|
||||
|
||||
-- Tileset properties
|
||||
tileset.properties.kind = "terrain"
|
||||
assert(tileset.properties.kind == "terrain")
|
||||
assert(#tileset.properties == 1)
|
||||
|
||||
-- Tiles user data
|
||||
local tile1 = tileset:tile(1)
|
||||
tile1.color = Color(255, 0, 0)
|
||||
assert(tile1.color == Color(255, 0, 0))
|
||||
tile1.data = "solid"
|
||||
assert(tile1.data == "solid")
|
||||
tile1.data = nil
|
||||
assert(tile1.data == "")
|
||||
|
||||
tile1.properties.center = Point(2, 2)
|
||||
tile1.properties("ext").pivot = Point(5, 5)
|
||||
assert(tile1.properties.center == Point(2, 2))
|
||||
assert(tile1.properties("ext").pivot == Point(5, 5))
|
||||
assert(#tileset.properties == 1) -- Check that tileset properties are not set
|
||||
|
||||
local tile2 = tileset:tile(2)
|
||||
tile2.properties.center = Point(3, 2)
|
||||
tile2.properties.extra = 32
|
||||
assert(tile2.properties.center == Point(3, 2))
|
||||
assert(tile2.properties.extra == 32)
|
||||
assert(tile1.properties.center == Point(2, 2))
|
||||
assert(tile1.properties("ext").pivot == Point(5, 5))
|
||||
assert(#tileset.properties == 1) -- Check that tileset properties are not set
|
||||
assert(#tile1.properties == 1)
|
||||
assert(#tile1.properties("ext") == 1)
|
||||
assert(#tile2.properties == 2)
|
||||
app.undo()
|
||||
assert(#tile2.properties == 1)
|
||||
app.undo()
|
||||
assert(#tile2.properties == 0)
|
||||
app.redo()
|
||||
app.redo()
|
||||
assert(#tile2.properties == 2)
|
||||
|
||||
-- Undoable Tile.color and Tile.data
|
||||
assert(tile2.color == Color())
|
||||
tile2.color = Color(0, 0, 255)
|
||||
assert(tile2.color == Color(0, 0, 255))
|
||||
app.undo()
|
||||
assert(tile2.color == Color())
|
||||
|
||||
assert(tile2.data == "")
|
||||
tile2.data = "B"
|
||||
assert(tile2.data == "B")
|
||||
app.undo()
|
||||
assert(tile2.data == "")
|
||||
|
||||
-- Set all properties at once
|
||||
tile1.properties = { a=1, b=2.1 }
|
||||
assert(#tile1.properties == 2)
|
||||
assert(tile1.properties.a == 1)
|
||||
assert(tile1.properties.b == 2.1)
|
||||
|
||||
assert(#tile1.properties("ext") == 1)
|
||||
tile1.properties("ext", { x=2, y=3 })
|
||||
assert(#tile1.properties("ext") == 2)
|
||||
assert(tile1.properties("ext").x == 2)
|
||||
assert(tile1.properties("ext").y == 3)
|
||||
|
||||
end
|
@ -26,6 +26,7 @@ do
|
||||
tileset.name = "Default Land"
|
||||
assert(tileset.name == "Default Land")
|
||||
|
||||
-- Tileset user data
|
||||
assert(tileset.data == "")
|
||||
tileset.data = "land"
|
||||
assert(tileset.data == "land")
|
||||
@ -33,4 +34,18 @@ do
|
||||
assert(tileset.color == Color())
|
||||
tileset.color = Color(255, 0, 0)
|
||||
assert(tileset.color == Color(255, 0, 0))
|
||||
|
||||
-- Create extra tile
|
||||
app.useTool{
|
||||
tool='pencil',
|
||||
color=1,
|
||||
layer=tilemap,
|
||||
tilesetMode=TilesetMode.STACK,
|
||||
points={ Point(1, 1) }}
|
||||
assert(#tileset == 3)
|
||||
|
||||
-- Check that Tileset:getTile(ti) returns Tileset:tile(ti).image user data
|
||||
for ti=0,2 do
|
||||
assert(tileset:tile(ti).image.id == tileset:getTile(ti).id)
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user