1// Aseprite
2// Copyright (C) 2018-2019 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/script/docobj.h"
13#include "app/script/engine.h"
14#include "app/script/luacpp.h"
15#include "base/string.h"
16#include "doc/layer.h"
17#include "doc/object_ids.h"
18#include "doc/sprite.h"
19
20namespace app {
21namespace script {
22
23using namespace doc;
24
25namespace {
26
27struct LayersObj {
28 ObjectIds layers;
29
30 LayersObj(Sprite* sprite) {
31 for (const Layer* layer : sprite->root()->layers())
32 layers.push_back(layer->id());
33 }
34 LayersObj(LayerGroup* group) {
35 for (const Layer* layer : group->layers())
36 layers.push_back(layer->id());
37 }
38 LayersObj(const ObjectIds& layers)
39 : layers(layers) {
40 }
41
42 LayersObj(const LayersObj&) = delete;
43 LayersObj& operator=(const LayersObj&) = delete;
44};
45
46int Layers_gc(lua_State* L)
47{
48 get_obj<LayersObj>(L, 1)->~LayersObj();
49 return 0;
50}
51
52int Layers_len(lua_State* L)
53{
54 auto obj = get_obj<LayersObj>(L, 1);
55 lua_pushinteger(L, obj->layers.size());
56 return 1;
57}
58
59int Layers_index(lua_State* L)
60{
61 auto obj = get_obj<LayersObj>(L, 1);
62
63 // Index by layer name
64 if (lua_type(L, 2) == LUA_TSTRING) {
65 if (const char* name = lua_tostring(L, 2)) {
66 for (ObjectId layerId : obj->layers) {
67 Layer* layer = doc::get<Layer>(layerId);
68 if (layer &&
69 base::utf8_icmp(layer->name(), name) == 0) {
70 push_docobj<Layer>(L, layerId);
71 return 1;
72 }
73 }
74 }
75 }
76
77 const int i = lua_tonumber(L, 2);
78 if (i >= 1 && i <= int(obj->layers.size()))
79 push_docobj<Layer>(L, obj->layers[i-1]);
80 else
81 lua_pushnil(L);
82 return 1;
83}
84
85const luaL_Reg Layers_methods[] = {
86 { "__gc", Layers_gc },
87 { "__len", Layers_len },
88 { "__index", Layers_index },
89 { nullptr, nullptr }
90};
91
92} // anonymous namespace
93
94DEF_MTNAME(LayersObj);
95
96void register_layers_class(lua_State* L)
97{
98 using Layers = LayersObj;
99 REG_CLASS(L, Layers);
100}
101
102void push_sprite_layers(lua_State* L, Sprite* sprite)
103{
104 push_new<LayersObj>(L, sprite);
105}
106
107void push_group_layers(lua_State* L, LayerGroup* group)
108{
109 push_new<LayersObj>(L, group);
110}
111
112void push_layers(lua_State* L, const ObjectIds& layers)
113{
114 push_new<LayersObj>(L, layers);
115}
116
117} // namespace script
118} // namespace app
119