1 // Aseprite Document Library 2 // Copyright (c) 2016, 2018 David Capello 3 // 4 // This file is released under the terms of the MIT license. 5 // Read LICENSE.txt for more information. 6 7 #ifdef HAVE_CONFIG_H 8 #include "config.h" 9 #endif 10 11 #include "doc/selected_layers.h" 12 13 #include "base/base.h" 14 #include "base/debug.h" 15 #include "base/serialization.h" 16 #include "doc/layer.h" 17 #include "doc/sprite.h" 18 19 #include <iostream> 20 21 namespace doc { 22 23 using namespace base::serialization; 24 using namespace base::serialization::little_endian; 25 clear()26void SelectedLayers::clear() 27 { 28 m_set.clear(); 29 } 30 insert(Layer * layer)31void SelectedLayers::insert(Layer* layer) 32 { 33 ASSERT(layer); 34 m_set.insert(layer); 35 } 36 erase(Layer * layer)37void SelectedLayers::erase(Layer* layer) 38 { 39 m_set.erase(layer); 40 } 41 contains(Layer * layer) const42bool SelectedLayers::contains(Layer* layer) const 43 { 44 return m_set.find(layer) != m_set.end(); 45 } 46 hasSameParent() const47bool SelectedLayers::hasSameParent() const 48 { 49 Layer* parent = nullptr; 50 for (auto layer : *this) { 51 if (parent) { 52 if (layer->parent() != parent) 53 return false; 54 } 55 else 56 parent = layer->parent(); 57 } 58 return true; 59 } 60 toLayerList() const61LayerList SelectedLayers::toLayerList() const 62 { 63 LayerList output; 64 65 if (empty()) 66 return output; 67 68 ASSERT(*begin()); 69 ASSERT((*begin())->sprite()); 70 71 for (Layer* layer = (*begin())->sprite()->firstBrowsableLayer(); 72 layer != nullptr; 73 layer = layer->getNextBrowsable()) { 74 if (contains(layer)) 75 output.push_back(layer); 76 } 77 78 return output; 79 } 80 removeChildrenIfParentIsSelected()81void SelectedLayers::removeChildrenIfParentIsSelected() 82 { 83 SelectedLayers removeThese; 84 85 for (Layer* child : *this) { 86 Layer* parent = child->parent(); 87 while (parent) { 88 if (contains(parent)) { 89 removeThese.insert(child); 90 break; 91 } 92 parent = parent->parent(); 93 } 94 } 95 96 for (Layer* child : removeThese) 97 erase(child); 98 } 99 selectAllLayers(LayerGroup * group)100void SelectedLayers::selectAllLayers(LayerGroup* group) 101 { 102 for (Layer* layer : group->layers()) { 103 if (layer->isGroup()) 104 selectAllLayers(static_cast<LayerGroup*>(layer)); 105 insert(layer); 106 } 107 } 108 expandCollapsedGroups()109void SelectedLayers::expandCollapsedGroups() 110 { 111 auto copy = m_set; 112 for (Layer* layer : copy) { 113 if (layer->isGroup() && layer->isCollapsed()) 114 selectAllLayers(static_cast<LayerGroup*>(layer)); 115 } 116 } 117 displace(layer_t layerDelta)118void SelectedLayers::displace(layer_t layerDelta) 119 { 120 // Do nothing case 121 if (layerDelta == 0) 122 return; 123 124 const SelectedLayers original = *this; 125 126 retry:; 127 clear(); 128 129 for (auto it : original) { 130 Layer* layer = it; 131 132 if (layerDelta > 0) { 133 for (layer_t i=0; layer && i<layerDelta; ++i) 134 layer = layer->getNextBrowsable(); 135 } 136 else if (layerDelta < 0) { 137 for (layer_t i=0; layer && i>layerDelta; --i) { 138 layer = layer->getPreviousBrowsable(); 139 } 140 } 141 142 if (layer) { 143 insert(layer); 144 } 145 // If some layer is outside the range it means that the delta is 146 // too big (out of bounds), we reduce the delta and try again the 147 // whole process. 148 else { 149 layerDelta -= SGN(layerDelta); 150 if (layerDelta == 0) { 151 m_set = original.m_set; 152 break; 153 } 154 goto retry; 155 } 156 } 157 } 158 159 // This will select: 160 // 1. all visible children in case the parent is selected and none of 161 // its children is selected. 162 // 2. all parent if one children is selected propagateSelection()163void SelectedLayers::propagateSelection() 164 { 165 SelectedLayers newSel; 166 167 for (Layer* layer : *this) { 168 if (!layer->isGroup()) 169 continue; 170 171 LayerList children; 172 static_cast<LayerGroup*>(layer)->allLayers(children); 173 174 bool allDeselected = true; 175 for (Layer* child : children) { 176 if (contains(child)) { 177 allDeselected = false; 178 break; 179 } 180 } 181 if (allDeselected) { 182 for (Layer* child : children) { 183 if (child->isVisible()) 184 newSel.insert(child); 185 } 186 } 187 } 188 189 for (Layer* layer : *this) { 190 Layer* parent = layer->parent(); 191 while (parent != layer->sprite()->root() && 192 !contains(parent)) { 193 newSel.insert(parent); 194 parent = parent->parent(); 195 } 196 } 197 198 for (Layer* layer : newSel) 199 insert(layer); 200 } 201 write(std::ostream & os) const202bool SelectedLayers::write(std::ostream& os) const 203 { 204 write32(os, size()); 205 for (const Layer* layer : *this) 206 write32(os, layer->id()); 207 return os.good(); 208 } 209 read(std::istream & is)210bool SelectedLayers::read(std::istream& is) 211 { 212 clear(); 213 214 int nlayers = read32(is); 215 for (int i=0; i<nlayers && is; ++i) { 216 ObjectId id = read32(is); 217 Layer* layer = doc::get<Layer>(id); 218 219 // Check that the layer does exist. You will see a little trick in 220 // UndoCommand::onExecute() deserializing the DocumentRange stream 221 // after the undo/redo is executed so layers exist at this point. 222 223 // TODO This should be an assert, but there is a bug that make this fail 224 //ASSERT(layer); 225 226 if (layer) 227 insert(layer); 228 } 229 return is.good(); 230 } 231 232 } // namespace doc 233