1 | // Aseprite Document Library |
2 | // Copyright (C) 2019-2021 Igara Studio S.A. |
3 | // Copyright (C) 2001-2018 David Capello |
4 | // |
5 | // This file is released under the terms of the MIT license. |
6 | // Read LICENSE.txt for more information. |
7 | |
8 | #ifndef DOC_LAYER_H_INCLUDED |
9 | #define DOC_LAYER_H_INCLUDED |
10 | #pragma once |
11 | |
12 | #include "doc/blend_mode.h" |
13 | #include "doc/cel_list.h" |
14 | #include "doc/frame.h" |
15 | #include "doc/layer_list.h" |
16 | #include "doc/object.h" |
17 | #include "doc/with_user_data.h" |
18 | |
19 | #include <string> |
20 | |
21 | namespace doc { |
22 | |
23 | class Cel; |
24 | class Grid; |
25 | class Image; |
26 | class Layer; |
27 | class LayerGroup; |
28 | class LayerImage; |
29 | class Sprite; |
30 | |
31 | ////////////////////////////////////////////////////////////////////// |
32 | // Layer class |
33 | |
34 | enum class LayerFlags { |
35 | None = 0, |
36 | Visible = 1, // Can be read |
37 | Editable = 2, // Can be written |
38 | LockMove = 4, // Cannot be moved |
39 | Background = 8, // Stack order cannot be changed |
40 | Continuous = 16, // Prefer to link cels when the user copy them |
41 | Collapsed = 32, // Prefer to show this group layer collapsed |
42 | Reference = 64, // Is a reference layer |
43 | |
44 | PersistentFlagsMask = 0xffff, |
45 | |
46 | Internal_WasVisible = 0x10000, // Was visible in the alternative state (Alt+click) |
47 | |
48 | BackgroundLayerFlags = LockMove | Background, |
49 | }; |
50 | |
51 | class Layer : public WithUserData { |
52 | protected: |
53 | Layer(ObjectType type, Sprite* sprite); |
54 | |
55 | public: |
56 | virtual ~Layer(); |
57 | |
58 | virtual int getMemSize() const override; |
59 | |
60 | const std::string& name() const { return m_name; } |
61 | void setName(const std::string& name) { m_name = name; } |
62 | |
63 | Sprite* sprite() const { return m_sprite; } |
64 | LayerGroup* parent() const { return m_parent; } |
65 | void setParent(LayerGroup* group) { m_parent = group; } |
66 | |
67 | // Gets the previous sibling of this layer. |
68 | Layer* getPrevious() const; |
69 | Layer* getNext() const; |
70 | |
71 | Layer* getPreviousBrowsable() const; |
72 | Layer* getNextBrowsable() const; |
73 | |
74 | Layer* getPreviousInWholeHierarchy() const; |
75 | Layer* getNextInWholeHierarchy() const; |
76 | |
77 | bool isImage() const { return (type() == ObjectType::LayerImage || |
78 | type() == ObjectType::LayerTilemap); } |
79 | bool isGroup() const { return type() == ObjectType::LayerGroup; } |
80 | bool isTilemap() const { return type() == ObjectType::LayerTilemap; } |
81 | virtual bool isBrowsable() const { return false; } |
82 | |
83 | bool isBackground() const { return hasFlags(LayerFlags::Background); } |
84 | bool isTransparent() const { return !hasFlags(LayerFlags::Background); } |
85 | bool isVisible() const { return hasFlags(LayerFlags::Visible); } |
86 | bool isEditable() const { return hasFlags(LayerFlags::Editable); } |
87 | bool isMovable() const { return !hasFlags(LayerFlags::LockMove); } |
88 | bool isContinuous() const { return hasFlags(LayerFlags::Continuous); } |
89 | bool isCollapsed() const { return hasFlags(LayerFlags::Collapsed); } |
90 | bool isExpanded() const { return !hasFlags(LayerFlags::Collapsed); } |
91 | bool isReference() const { return hasFlags(LayerFlags::Reference); } |
92 | |
93 | bool isVisibleHierarchy() const; |
94 | bool isEditableHierarchy() const; |
95 | bool canEditPixels() const; |
96 | bool hasAncestor(const Layer* ancestor) const; |
97 | |
98 | void setBackground(bool state) { switchFlags(LayerFlags::Background, state); } |
99 | void setVisible (bool state) { switchFlags(LayerFlags::Visible, state); } |
100 | void setEditable (bool state) { switchFlags(LayerFlags::Editable, state); } |
101 | void setMovable (bool state) { switchFlags(LayerFlags::LockMove, !state); } |
102 | void setContinuous(bool state) { switchFlags(LayerFlags::Continuous, state); } |
103 | void setCollapsed (bool state) { switchFlags(LayerFlags::Collapsed, state); } |
104 | void setReference (bool state) { switchFlags(LayerFlags::Reference, state); } |
105 | |
106 | LayerFlags flags() const { |
107 | return m_flags; |
108 | } |
109 | |
110 | bool hasFlags(LayerFlags flags) const { |
111 | return (int(m_flags) & int(flags)) == int(flags); |
112 | } |
113 | |
114 | void setFlags(LayerFlags flags) { |
115 | m_flags = flags; |
116 | } |
117 | |
118 | void switchFlags(LayerFlags flags, bool state) { |
119 | if (state) |
120 | m_flags = LayerFlags(int(m_flags) | int(flags)); |
121 | else |
122 | m_flags = LayerFlags(int(m_flags) & ~int(flags)); |
123 | } |
124 | |
125 | virtual Grid grid() const; |
126 | virtual Cel* cel(frame_t frame) const; |
127 | virtual void getCels(CelList& cels) const = 0; |
128 | virtual void displaceFrames(frame_t fromThis, frame_t delta) = 0; |
129 | |
130 | private: |
131 | std::string m_name; // layer name |
132 | Sprite* m_sprite; // owner of the layer |
133 | LayerGroup* m_parent; // parent layer |
134 | LayerFlags m_flags; // stack order cannot be changed |
135 | |
136 | // Disable assigment |
137 | Layer& operator=(const Layer& other); |
138 | }; |
139 | |
140 | ////////////////////////////////////////////////////////////////////// |
141 | // LayerImage class |
142 | |
143 | class LayerImage : public Layer { |
144 | public: |
145 | LayerImage(ObjectType type, Sprite* sprite); |
146 | explicit LayerImage(Sprite* sprite); |
147 | virtual ~LayerImage(); |
148 | |
149 | virtual int getMemSize() const override; |
150 | |
151 | BlendMode blendMode() const { return m_blendmode; } |
152 | void setBlendMode(BlendMode blendmode) { m_blendmode = blendmode; } |
153 | |
154 | int opacity() const { return m_opacity; } |
155 | void setOpacity(int opacity) { m_opacity = opacity; } |
156 | |
157 | void addCel(Cel *cel); |
158 | void removeCel(Cel *cel); |
159 | void moveCel(Cel *cel, frame_t frame); |
160 | |
161 | Cel* cel(frame_t frame) const override; |
162 | void getCels(CelList& cels) const override; |
163 | void displaceFrames(frame_t fromThis, frame_t delta) override; |
164 | |
165 | Cel* getLastCel() const; |
166 | CelConstIterator findCelIterator(frame_t frame) const; |
167 | CelIterator findCelIterator(frame_t frame); |
168 | CelIterator findFirstCelIteratorAfter(frame_t firstAfterFrame); |
169 | |
170 | void configureAsBackground(); |
171 | |
172 | CelIterator getCelBegin() { return m_cels.begin(); } |
173 | CelIterator getCelEnd() { return m_cels.end(); } |
174 | CelConstIterator getCelBegin() const { return m_cels.begin(); } |
175 | CelConstIterator getCelEnd() const { return m_cels.end(); } |
176 | int getCelsCount() const { return (int)m_cels.size(); } |
177 | |
178 | private: |
179 | void destroyAllCels(); |
180 | |
181 | BlendMode m_blendmode; |
182 | int m_opacity; |
183 | CelList m_cels; // List of all cels inside this layer used by frames. |
184 | }; |
185 | |
186 | ////////////////////////////////////////////////////////////////////// |
187 | // LayerGroup class |
188 | |
189 | class LayerGroup : public Layer { |
190 | public: |
191 | explicit LayerGroup(Sprite* sprite); |
192 | virtual ~LayerGroup(); |
193 | |
194 | virtual int getMemSize() const override; |
195 | |
196 | const LayerList& layers() const { return m_layers; } |
197 | int layersCount() const { return (int)m_layers.size(); } |
198 | |
199 | void addLayer(Layer* layer); |
200 | void removeLayer(Layer* layer); |
201 | void insertLayer(Layer* layer, Layer* after); |
202 | void stackLayer(Layer* layer, Layer* after); |
203 | |
204 | Layer* firstLayer() const { return (m_layers.empty() ? nullptr: m_layers.front()); } |
205 | Layer* firstLayerInWholeHierarchy() const; |
206 | Layer* lastLayer() const { return (m_layers.empty() ? nullptr: m_layers.back()); } |
207 | |
208 | void allLayers(LayerList& list) const; |
209 | layer_t allLayersCount() const; |
210 | bool hasVisibleReferenceLayers() const; |
211 | void allVisibleLayers(LayerList& list) const; |
212 | void allVisibleReferenceLayers(LayerList& list) const; |
213 | void allBrowsableLayers(LayerList& list) const; |
214 | |
215 | void getCels(CelList& cels) const override; |
216 | void displaceFrames(frame_t fromThis, frame_t delta) override; |
217 | |
218 | bool isBrowsable() const override { |
219 | return isGroup() && isExpanded() && !m_layers.empty(); |
220 | } |
221 | |
222 | private: |
223 | void destroyAllLayers(); |
224 | |
225 | LayerList m_layers; |
226 | }; |
227 | |
228 | } // namespace doc |
229 | |
230 | #endif |
231 | |