1// Aseprite
2// Copyright (C) 2018-2022 Igara Studio S.A.
3// Copyright (C) 2018 David Capello
4//
5// This program is distributed under the terms of
6// the End-User License Agreement for Aseprite.
7
8#ifdef HAVE_CONFIG_H
9#include "config.h"
10#endif
11
12#include "app/cmd/replace_image.h"
13#include "app/cmd/set_cel_opacity.h"
14#include "app/cmd/set_cel_position.h"
15#include "app/doc_api.h"
16#include "app/script/docobj.h"
17#include "app/script/engine.h"
18#include "app/script/luacpp.h"
19#include "app/script/userdata.h"
20#include "doc/cel.h"
21#include "doc/sprite.h"
22
23namespace app {
24namespace script {
25
26using namespace doc;
27
28namespace {
29
30int Cel_eq(lua_State* L)
31{
32 const auto a = may_get_docobj<Cel>(L, 1);
33 const auto b = may_get_docobj<Cel>(L, 2);
34 lua_pushboolean(L, (!a && !b) || (a && b && a->id() == b->id()));
35 return 1;
36}
37
38int Cel_get_sprite(lua_State* L)
39{
40 const auto cel = get_docobj<Cel>(L, 1);
41 push_docobj(L, cel->sprite());
42 return 1;
43}
44
45int Cel_get_layer(lua_State* L)
46{
47 const auto cel = get_docobj<Cel>(L, 1);
48 push_docobj(L, (Layer*)cel->layer());
49 return 1;
50}
51
52int Cel_get_frame(lua_State* L)
53{
54 const auto cel = get_docobj<Cel>(L, 1);
55 if (auto sprite = cel->sprite())
56 push_sprite_frame(L, sprite, cel->frame());
57 else
58 lua_pushnil(L);
59 return 1;
60}
61
62int Cel_get_frameNumber(lua_State* L)
63{
64 const auto cel = get_docobj<Cel>(L, 1);
65 lua_pushinteger(L, cel->frame()+1);
66 return 1;
67}
68
69int Cel_get_image(lua_State* L)
70{
71 auto cel = get_docobj<Cel>(L, 1);
72 push_cel_image(L, cel);
73 return 1;
74}
75
76int Cel_get_position(lua_State* L)
77{
78 const auto cel = get_docobj<Cel>(L, 1);
79 push_new<gfx::Point>(L, cel->position());
80 return 1;
81}
82
83int Cel_get_bounds(lua_State* L)
84{
85 const auto cel = get_docobj<Cel>(L, 1);
86 push_new<gfx::Rect>(L, cel->bounds());
87 return 1;
88}
89
90int Cel_get_opacity(lua_State* L)
91{
92 const auto cel = get_docobj<Cel>(L, 1);
93 lua_pushinteger(L, cel->opacity());
94 return 1;
95}
96
97int Cel_set_frame(lua_State* L)
98{
99 const auto cel = get_docobj<Cel>(L, 1);
100 doc::frame_t frame = get_frame_number_from_arg(L, 2);
101
102 if (cel->frame() == frame)
103 return 0;
104
105 Tx tx;
106 Doc* doc = static_cast<Doc*>(cel->document());
107 DocApi api = doc->getApi(tx);
108 api.moveCel(cel->layer(), cel->frame(),
109 cel->layer(), frame);
110 tx.commit();
111 return 0;
112}
113
114int Cel_set_image(lua_State* L)
115{
116 auto cel = get_docobj<Cel>(L, 1);
117 auto srcImage = get_image_from_arg(L, 2);
118 ImageRef newImage(Image::createCopy(srcImage));
119
120 Tx tx;
121 tx(new cmd::ReplaceImage(cel->sprite(),
122 cel->imageRef(),
123 newImage));
124 tx.commit();
125 return 0;
126}
127
128int Cel_set_position(lua_State* L)
129{
130 auto cel = get_docobj<Cel>(L, 1);
131 const gfx::Point pos = convert_args_into_point(L, 2);
132 Tx tx;
133 tx(new cmd::SetCelPosition(cel, pos.x, pos.y));
134 tx.commit();
135 return 0;
136}
137
138int Cel_set_opacity(lua_State* L)
139{
140 auto cel = get_docobj<Cel>(L, 1);
141 Tx tx;
142 tx(new cmd::SetCelOpacity(cel, lua_tointeger(L, 2)));
143 tx.commit();
144 return 0;
145}
146
147const luaL_Reg Cel_methods[] = {
148 { "__eq", Cel_eq },
149 { nullptr, nullptr }
150};
151
152const Property Cel_properties[] = {
153 { "sprite", Cel_get_sprite, nullptr },
154 { "layer", Cel_get_layer, nullptr },
155 { "frame", Cel_get_frame, Cel_set_frame },
156 { "frameNumber", Cel_get_frameNumber, Cel_set_frame },
157 { "image", Cel_get_image, Cel_set_image },
158 { "bounds", Cel_get_bounds, nullptr },
159 { "position", Cel_get_position, Cel_set_position },
160 { "opacity", Cel_get_opacity, Cel_set_opacity },
161 { "color", UserData_get_color<Cel>, UserData_set_color<Cel> },
162 { "data", UserData_get_text<Cel>, UserData_set_text<Cel> },
163 { nullptr, nullptr, nullptr }
164};
165
166} // anonymous namespace
167
168DEF_MTNAME(Cel);
169
170void register_cel_class(lua_State* L)
171{
172 using Cel = doc::Cel;
173 REG_CLASS(L, Cel);
174 REG_CLASS_PROPERTIES(L, Cel);
175}
176
177void push_sprite_cel(lua_State* L, Cel* cel)
178{
179 push_docobj(L, cel);
180}
181
182} // namespace script
183} // namespace app
184