1 // Aseprite
2 // Copyright (C) 2001-2018 David Capello
3 //
4 // This program is distributed under the terms of
5 // the End-User License Agreement for Aseprite.
6
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10
11 #include "app/doc_range.h"
12
13 #include "base/serialization.h"
14 #include "doc/cel.h"
15 #include "doc/image.h"
16 #include "doc/layer.h"
17 #include "doc/sprite.h"
18
19 #include <iostream>
20
21 namespace app {
22
23 using namespace base::serialization;
24 using namespace base::serialization::little_endian;
25 using namespace doc;
26
DocRange()27 DocRange::DocRange()
28 : m_type(kNone)
29 , m_flags(m_type)
30 , m_selectingFromLayer(nullptr)
31 , m_selectingFromFrame(-1)
32 {
33 }
34
DocRange(Cel * cel)35 DocRange::DocRange(Cel* cel)
36 : m_type(kCels)
37 , m_flags(m_type)
38 , m_selectingFromLayer(nullptr)
39 , m_selectingFromFrame(-1)
40 {
41 m_selectedLayers.insert(cel->layer());
42 m_selectedFrames.insert(cel->frame());
43 }
44
clearRange()45 void DocRange::clearRange()
46 {
47 m_type = kNone;
48 m_flags = kNone;
49 m_selectedLayers.clear();
50 m_selectedFrames.clear();
51 }
52
startRange(Layer * fromLayer,frame_t fromFrame,Type type)53 void DocRange::startRange(Layer* fromLayer, frame_t fromFrame, Type type)
54 {
55 m_type = type;
56 m_flags |= type;
57 m_selectingFromLayer = fromLayer;
58 m_selectingFromFrame = fromFrame;
59
60 if (fromLayer)
61 m_selectedLayers.insert(fromLayer);
62 if (fromFrame >= 0)
63 m_selectedFrames.insert(fromFrame);
64 }
65
endRange(Layer * toLayer,frame_t toFrame)66 void DocRange::endRange(Layer* toLayer, frame_t toFrame)
67 {
68 ASSERT(enabled());
69
70 if (m_selectingFromLayer && toLayer)
71 selectLayerRange(m_selectingFromLayer, toLayer);
72
73 if (m_selectingFromFrame >= 0)
74 selectFrameRange(m_selectingFromFrame, toFrame);
75 }
76
selectLayer(Layer * layer)77 void DocRange::selectLayer(Layer* layer)
78 {
79 if (m_type == kNone)
80 m_type = kLayers;
81 m_flags |= kLayers;
82
83 m_selectedLayers.insert(layer);
84 }
85
selectLayers(const SelectedLayers & selLayers)86 void DocRange::selectLayers(const SelectedLayers& selLayers)
87 {
88 if (m_type == kNone)
89 m_type = kLayers;
90 m_flags |= kLayers;
91
92 for (auto layer : selLayers)
93 m_selectedLayers.insert(layer);
94 }
95
contains(const Layer * layer) const96 bool DocRange::contains(const Layer* layer) const
97 {
98 if (enabled())
99 return m_selectedLayers.contains(const_cast<Layer*>(layer));
100 else
101 return false;
102 }
103
contains(const Layer * layer,const frame_t frame) const104 bool DocRange::contains(const Layer* layer,
105 const frame_t frame) const
106 {
107 switch (m_type) {
108 case DocRange::kNone:
109 return false;
110 case DocRange::kCels:
111 return contains(layer) && contains(frame);
112 case DocRange::kFrames:
113 if (contains(frame)) {
114 if ((m_flags & (kCels | kLayers)) != 0)
115 return contains(layer);
116 else
117 return true;
118 }
119 break;
120 case DocRange::kLayers:
121 if (contains(layer)) {
122 if ((m_flags & (kCels | kFrames)) != 0)
123 return contains(frame);
124 else
125 return true;
126 }
127 break;
128 }
129 return false;
130 }
131
displace(layer_t layerDelta,frame_t frameDelta)132 void DocRange::displace(layer_t layerDelta, frame_t frameDelta)
133 {
134 m_selectedLayers.displace(layerDelta);
135 m_selectedFrames.displace(frameDelta);
136 }
137
convertToCels(const Sprite * sprite)138 bool DocRange::convertToCels(const Sprite* sprite)
139 {
140 switch (m_type) {
141 case DocRange::kNone:
142 return false;
143 case DocRange::kCels:
144 break;
145 case DocRange::kFrames: {
146 if ((m_flags & (kCels | kLayers)) == 0) {
147 for (auto layer : sprite->allBrowsableLayers())
148 m_selectedLayers.insert(layer);
149 }
150 m_type = DocRange::kCels;
151 break;
152 }
153 case DocRange::kLayers:
154 if ((m_flags & (kCels | kFrames)) == 0)
155 selectFrameRange(0, sprite->lastFrame());
156 m_type = DocRange::kCels;
157 break;
158 }
159 return true;
160 }
161
write(std::ostream & os) const162 bool DocRange::write(std::ostream& os) const
163 {
164 write32(os, m_type);
165 write32(os, m_flags);
166
167 if (!m_selectedLayers.write(os)) return false;
168 if (!m_selectedFrames.write(os)) return false;
169
170 write32(os, m_selectingFromLayer ? m_selectingFromLayer->id(): 0);
171 write32(os, m_selectingFromFrame);
172 return os.good();
173 }
174
read(std::istream & is)175 bool DocRange::read(std::istream& is)
176 {
177 clearRange();
178
179 m_type = (Type)read32(is);
180 m_flags = read32(is);
181
182 if (!m_selectedLayers.read(is)) return false;
183 if (!m_selectedFrames.read(is)) return false;
184
185 ObjectId id = read32(is);
186 m_selectingFromLayer = doc::get<Layer>(id);
187 m_selectingFromFrame = read32(is);
188 return is.good();
189 }
190
selectLayerRange(Layer * fromLayer,Layer * toLayer)191 void DocRange::selectLayerRange(Layer* fromLayer, Layer* toLayer)
192 {
193 ASSERT(fromLayer);
194 ASSERT(toLayer);
195
196 bool goNext = false;
197 bool goPrev = false;
198 Layer* it;
199
200 if (fromLayer != toLayer) {
201 it = m_selectingFromLayer;
202 while (it) {
203 if (it == toLayer) {
204 goNext = true;
205 break;
206 }
207 it = it->getNextBrowsable();
208 }
209
210 if (!goNext) {
211 it = m_selectingFromLayer;
212 while (it) {
213 if (it == toLayer) {
214 goPrev = true;
215 break;
216 }
217 it = it->getPreviousBrowsable();
218 }
219 }
220 }
221
222 it = m_selectingFromLayer;
223 do {
224 m_selectedLayers.insert(it);
225 if (it == toLayer)
226 break;
227
228 if (goNext)
229 it = it->getNextBrowsable();
230 else if (goPrev)
231 it = it->getPreviousBrowsable();
232 else
233 break;
234 } while (it);
235 }
236
selectFrameRange(frame_t fromFrame,frame_t toFrame)237 void DocRange::selectFrameRange(frame_t fromFrame, frame_t toFrame)
238 {
239 m_selectedFrames.insert(fromFrame, toFrame);
240 }
241
242 } // namespace app
243