2019-04-25 08:14:20 +08:00
|
|
|
// Aseprite
|
2022-02-22 02:30:09 +08:00
|
|
|
// Copyright (C) 2019-2022 Igara Studio S.A.
|
2019-04-25 08:14:20 +08:00
|
|
|
//
|
|
|
|
// 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/script/values.h"
|
|
|
|
|
|
|
|
#include "app/pref/preferences.h"
|
|
|
|
#include "app/script/engine.h"
|
|
|
|
#include "app/script/luacpp.h"
|
2022-12-28 01:11:05 +08:00
|
|
|
#include "doc/remap.h"
|
2019-04-25 08:14:20 +08:00
|
|
|
|
2022-09-29 23:09:06 +08:00
|
|
|
#include <any>
|
2022-12-31 01:51:43 +08:00
|
|
|
#include <variant>
|
2022-09-29 23:09:06 +08:00
|
|
|
|
2019-04-25 08:14:20 +08:00
|
|
|
namespace app {
|
|
|
|
namespace script {
|
|
|
|
|
|
|
|
// TODO this is similar to app::Param<> specializations::fromLua() specializations
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// bool
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const bool& value) {
|
|
|
|
lua_pushboolean(L, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
bool get_value_from_lua(lua_State* L, int index) {
|
|
|
|
return lua_toboolean(L, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// int
|
|
|
|
|
|
|
|
template<>
|
2022-12-31 01:51:43 +08:00
|
|
|
void push_value_to_lua(lua_State* L, const int8_t& value) { lua_pushinteger(L, value); }
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const int16_t& value) { lua_pushinteger(L, value); }
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const int32_t& value) { lua_pushinteger(L, value); }
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const int64_t& value) { lua_pushinteger(L, value); }
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const uint8_t& value) { lua_pushinteger(L, value); }
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const uint16_t& value) { lua_pushinteger(L, value); }
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const uint32_t& value) { lua_pushinteger(L, value); }
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const uint64_t& value) { lua_pushinteger(L, value); }
|
2019-04-25 08:14:20 +08:00
|
|
|
|
|
|
|
template<>
|
|
|
|
int get_value_from_lua(lua_State* L, int index) {
|
|
|
|
return lua_tointeger(L, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// double
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const double& value) {
|
|
|
|
lua_pushnumber(L, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
double get_value_from_lua(lua_State* L, int index) {
|
|
|
|
return lua_tonumber(L, index);
|
|
|
|
}
|
|
|
|
|
2022-12-31 01:51:43 +08:00
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// fixed
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const doc::UserData::Fixed& value) {
|
|
|
|
lua_pushnumber(L, fixmath::fixtof(value.value));
|
|
|
|
}
|
|
|
|
|
2019-04-25 08:14:20 +08:00
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// std::string
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const std::string& value) {
|
|
|
|
lua_pushstring(L, value.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
std::string get_value_from_lua(lua_State* L, int index) {
|
|
|
|
if (const char* v = lua_tostring(L, index))
|
|
|
|
return std::string(v);
|
|
|
|
else
|
|
|
|
return std::string();
|
|
|
|
}
|
|
|
|
|
2022-12-28 01:11:05 +08:00
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-29 23:09:06 +08:00
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// std::any
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const std::any& value) {
|
|
|
|
if (!value.has_value())
|
|
|
|
lua_pushnil(L);
|
2022-12-28 02:53:41 +08:00
|
|
|
else if (auto v = std::any_cast<bool>(&value))
|
2022-09-29 23:09:06 +08:00
|
|
|
push_value_to_lua(L, *v);
|
2022-12-28 02:53:41 +08:00
|
|
|
else if (auto v = std::any_cast<int>(&value))
|
2022-09-29 23:09:06 +08:00
|
|
|
push_value_to_lua(L, *v);
|
2022-12-28 02:53:41 +08:00
|
|
|
else if (auto v = std::any_cast<std::string>(&value))
|
2022-12-28 01:11:05 +08:00
|
|
|
push_value_to_lua(L, *v);
|
2022-12-28 02:53:41 +08:00
|
|
|
else if (auto v = std::any_cast<const doc::Remap*>(&value))
|
|
|
|
push_value_to_lua(L, **v);
|
2022-12-28 02:54:41 +08:00
|
|
|
else if (auto v = std::any_cast<const doc::Tileset*>(&value))
|
|
|
|
push_tileset(L, *v);
|
2022-09-29 23:09:06 +08:00
|
|
|
else {
|
|
|
|
ASSERT(false);
|
|
|
|
throw std::runtime_error("Cannot convert type inside std::any");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-25 08:14:20 +08:00
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// Color
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const app::Color& value) {
|
|
|
|
push_obj(L, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
app::Color get_value_from_lua(lua_State* L, int index) {
|
|
|
|
return convert_args_into_color(L, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// Point
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const gfx::Point& value) {
|
|
|
|
push_obj(L, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
gfx::Point get_value_from_lua(lua_State* L, int index) {
|
|
|
|
return convert_args_into_point(L, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// Size
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const gfx::Size& value) {
|
|
|
|
push_obj(L, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
gfx::Size get_value_from_lua(lua_State* L, int index) {
|
|
|
|
return convert_args_into_size(L, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// Rect
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const gfx::Rect& value) {
|
|
|
|
push_obj(L, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
gfx::Rect get_value_from_lua(lua_State* L, int index) {
|
|
|
|
return convert_args_into_rect(L, index);
|
|
|
|
}
|
|
|
|
|
2020-05-21 03:34:43 +08:00
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// tools::InkType
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const app::tools::InkType& inkType) {
|
|
|
|
lua_pushinteger(L, (int)inkType);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
app::tools::InkType get_value_from_lua(lua_State* L, int index) {
|
|
|
|
if (lua_type(L, index) == LUA_TSTRING) {
|
|
|
|
if (const char* s = lua_tostring(L, index))
|
|
|
|
return app::tools::string_id_to_ink_type(s);
|
|
|
|
}
|
|
|
|
return (app::tools::InkType)lua_tointeger(L, index);
|
|
|
|
}
|
|
|
|
|
2020-08-22 05:07:37 +08:00
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// doc::tile_t
|
|
|
|
|
2022-12-31 01:51:43 +08:00
|
|
|
#if 0 // doc::tile_t matches uint32_t, and we have the uint32_t version already defined
|
2020-08-22 05:07:37 +08:00
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const doc::tile_t& value) {
|
|
|
|
lua_pushinteger(L, value);
|
|
|
|
}
|
2022-12-31 01:51:43 +08:00
|
|
|
#endif
|
2020-08-22 05:07:37 +08:00
|
|
|
|
|
|
|
template<>
|
|
|
|
doc::tile_t get_value_from_lua(lua_State* L, int index) {
|
|
|
|
return lua_tointeger(L, index);
|
|
|
|
}
|
|
|
|
|
2019-04-25 08:14:20 +08:00
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// enums
|
|
|
|
|
|
|
|
#define FOR_ENUM(T) \
|
|
|
|
template<> \
|
|
|
|
void push_value_to_lua(lua_State* L, const T& value) { \
|
|
|
|
lua_pushinteger(L, static_cast<int>(value)); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
template<> \
|
|
|
|
T get_value_from_lua(lua_State* L, int index) { \
|
|
|
|
return static_cast<T>(lua_tointeger(L, index)); \
|
|
|
|
}
|
|
|
|
|
|
|
|
FOR_ENUM(app::CelsTarget)
|
|
|
|
FOR_ENUM(app::ColorBar::ColorSelector)
|
2019-10-08 04:22:27 +08:00
|
|
|
FOR_ENUM(app::SpriteSheetDataFormat)
|
2019-04-25 08:14:20 +08:00
|
|
|
FOR_ENUM(app::SpriteSheetType)
|
|
|
|
FOR_ENUM(app::gen::BgType)
|
|
|
|
FOR_ENUM(app::gen::BrushPreview)
|
|
|
|
FOR_ENUM(app::gen::BrushType)
|
|
|
|
FOR_ENUM(app::gen::ColorProfileBehavior)
|
2022-02-22 02:30:09 +08:00
|
|
|
FOR_ENUM(app::gen::Downsampling)
|
2019-04-25 08:14:20 +08:00
|
|
|
FOR_ENUM(app::gen::EyedropperChannel)
|
|
|
|
FOR_ENUM(app::gen::EyedropperSample)
|
|
|
|
FOR_ENUM(app::gen::FillReferTo)
|
|
|
|
FOR_ENUM(app::gen::OnionskinType)
|
|
|
|
FOR_ENUM(app::gen::PaintingCursorType)
|
|
|
|
FOR_ENUM(app::gen::PivotPosition)
|
2019-03-29 09:07:32 +08:00
|
|
|
FOR_ENUM(app::gen::PixelConnectivity)
|
2019-04-25 08:14:20 +08:00
|
|
|
FOR_ENUM(app::gen::RightClickMode)
|
|
|
|
FOR_ENUM(app::gen::SelectionMode)
|
2021-04-13 03:57:02 +08:00
|
|
|
FOR_ENUM(app::gen::SequenceDecision)
|
2019-04-25 08:14:20 +08:00
|
|
|
FOR_ENUM(app::gen::StopAtGrid)
|
|
|
|
FOR_ENUM(app::gen::SymmetryMode)
|
|
|
|
FOR_ENUM(app::gen::TimelinePosition)
|
2020-04-20 21:18:12 +08:00
|
|
|
FOR_ENUM(app::gen::ToGrayAlgorithm)
|
2021-04-13 03:57:02 +08:00
|
|
|
FOR_ENUM(app::gen::WindowColorProfile)
|
2019-04-25 08:14:20 +08:00
|
|
|
FOR_ENUM(app::tools::FreehandAlgorithm)
|
|
|
|
FOR_ENUM(app::tools::RotationAlgorithm)
|
|
|
|
FOR_ENUM(doc::AniDir)
|
|
|
|
FOR_ENUM(doc::BrushPattern)
|
|
|
|
FOR_ENUM(doc::ColorMode)
|
2020-04-11 02:35:11 +08:00
|
|
|
FOR_ENUM(doc::RgbMapAlgorithm)
|
2020-04-23 23:05:09 +08:00
|
|
|
FOR_ENUM(filters::HueSaturationFilter::Mode)
|
2019-04-25 08:14:20 +08:00
|
|
|
FOR_ENUM(filters::TiledMode)
|
|
|
|
FOR_ENUM(render::OnionskinPosition)
|
|
|
|
|
2022-12-31 01:51:43 +08:00
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// UserData::Properties / VariantStruct
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const doc::UserData::Properties& value) {
|
|
|
|
// TODO convert a Properties map into a Lua table
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const doc::UserData::Vector& value) {
|
|
|
|
// TODO convert a Vector into a Lua table
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
void push_value_to_lua(lua_State* L, const doc::UserData::Variant& value) {
|
|
|
|
std::visit([L](auto&& v){ push_value_to_lua(L, v); }, value);
|
|
|
|
}
|
|
|
|
|
2019-04-25 08:14:20 +08:00
|
|
|
} // namespace script
|
|
|
|
} // namespace app
|