mirror of
https://github.com/aseprite/aseprite.git
synced 2024-10-06 06:50:07 +00:00
Delete unused tilesets after deleting tilemaps (fix #3876)
This commit is contained in:
parent
872267dc9b
commit
5bc432f289
@ -429,6 +429,9 @@
|
|||||||
<option id="base_index" type="int" default="1" />
|
<option id="base_index" type="int" default="1" />
|
||||||
<option id="cache_compressed_tilesets" type="bool" default="true" />
|
<option id="cache_compressed_tilesets" type="bool" default="true" />
|
||||||
</section>
|
</section>
|
||||||
|
<section id="tilemap">
|
||||||
|
<option id="show_delete_unused_tileset_alert" type="bool" default="true" />
|
||||||
|
</section>
|
||||||
</global>
|
</global>
|
||||||
|
|
||||||
<tool>
|
<tool>
|
||||||
|
@ -55,6 +55,13 @@ Automatic Remap
|
|||||||
||&OK||&Cancel"
|
||&OK||&Cancel"
|
||||||
END
|
END
|
||||||
cannot_delete_all_layers = Error<<You cannot delete all layers.||&OK
|
cannot_delete_all_layers = Error<<You cannot delete all layers.||&OK
|
||||||
|
deleting_tilemaps_will_delete_tilesets = <<<END
|
||||||
|
Warning
|
||||||
|
<<Deleting the following layers will delete their tilesets:
|
||||||
|
<<'{0}'
|
||||||
|
<<Do you want to continue anyway?
|
||||||
|
||&OK||&Cancel
|
||||||
|
END
|
||||||
cannot_file_overwrite_on_export = <<<END
|
cannot_file_overwrite_on_export = <<<END
|
||||||
Overwrite Warning
|
Overwrite Warning
|
||||||
<<You cannot Export with the same name (overwrite the original file).
|
<<You cannot Export with the same name (overwrite the original file).
|
||||||
@ -1698,6 +1705,7 @@ file_format_doesnt_support_alert = Show warning when saving a file with unsuppor
|
|||||||
export_animation_in_sequence_alert = Show warning when saving an animation as a sequence of static images
|
export_animation_in_sequence_alert = Show warning when saving an animation as a sequence of static images
|
||||||
overwrite_files_on_export_alert = Show warning when overwriting files on File > Export
|
overwrite_files_on_export_alert = Show warning when overwriting files on File > Export
|
||||||
overwrite_files_on_export_sprite_sheet_alert = Show warning when overwriting files on Export Sprite Sheet
|
overwrite_files_on_export_sprite_sheet_alert = Show warning when overwriting files on Export Sprite Sheet
|
||||||
|
delete_tilemap_delete_unused_tileset_alert = Show warning when deleting a tilemap will delete its unused tileset
|
||||||
image_format_alerts = Show options when saving files:
|
image_format_alerts = Show options when saving files:
|
||||||
advanced_mode_alert = Show alert when we enter to Advanced Mode
|
advanced_mode_alert = Show alert when we enter to Advanced Mode
|
||||||
invalid_fg_bg_color_alert = Show alert when drawing with index out of palette bounds
|
invalid_fg_bg_color_alert = Show alert when drawing with index out of palette bounds
|
||||||
|
@ -458,6 +458,8 @@
|
|||||||
pref="export_file.show_overwrite_files_alert" />
|
pref="export_file.show_overwrite_files_alert" />
|
||||||
<check id="overwrite_files_on_export_sprite_sheet_alert" text="@.overwrite_files_on_export_sprite_sheet_alert"
|
<check id="overwrite_files_on_export_sprite_sheet_alert" text="@.overwrite_files_on_export_sprite_sheet_alert"
|
||||||
pref="sprite_sheet.show_overwrite_files_alert" />
|
pref="sprite_sheet.show_overwrite_files_alert" />
|
||||||
|
<check id="delete_tilemap_delete_unused_tileset_alert" text="@.delete_tilemap_delete_unused_tileset_alert"
|
||||||
|
pref="tilemap.show_delete_unused_tileset_alert" />
|
||||||
<check id="advanced_mode_alert" text="@.advanced_mode_alert"
|
<check id="advanced_mode_alert" text="@.advanced_mode_alert"
|
||||||
pref="advanced_mode.show_alert" />
|
pref="advanced_mode.show_alert" />
|
||||||
<check id="invalid_fg_bg_color_alert" text="@.invalid_fg_bg_color_alert"
|
<check id="invalid_fg_bg_color_alert" text="@.invalid_fg_bg_color_alert"
|
||||||
|
@ -78,7 +78,7 @@ void AddTileset::addTileset(doc::Tileset* tileset)
|
|||||||
if (m_tilesetIndex == -1)
|
if (m_tilesetIndex == -1)
|
||||||
m_tilesetIndex = sprite->tilesets()->add(tileset);
|
m_tilesetIndex = sprite->tilesets()->add(tileset);
|
||||||
else
|
else
|
||||||
sprite->tilesets()->set(m_tilesetIndex, tileset);
|
sprite->tilesets()->add(m_tilesetIndex, tileset);
|
||||||
|
|
||||||
sprite->incrementVersion();
|
sprite->incrementVersion();
|
||||||
sprite->tilesets()->incrementVersion();
|
sprite->tilesets()->incrementVersion();
|
||||||
|
@ -11,20 +11,77 @@
|
|||||||
|
|
||||||
#include "app/app.h"
|
#include "app/app.h"
|
||||||
#include "app/commands/command.h"
|
#include "app/commands/command.h"
|
||||||
|
#include "app/cmd/remove_tileset.h"
|
||||||
#include "app/context_access.h"
|
#include "app/context_access.h"
|
||||||
#include "app/doc_api.h"
|
#include "app/doc_api.h"
|
||||||
#include "app/i18n/strings.h"
|
#include "app/i18n/strings.h"
|
||||||
#include "app/modules/gui.h"
|
#include "app/modules/gui.h"
|
||||||
#include "app/tx.h"
|
#include "app/tx.h"
|
||||||
|
#include "app/pref/preferences.h"
|
||||||
|
#include "app/ui/optional_alert.h"
|
||||||
#include "app/ui/status_bar.h"
|
#include "app/ui/status_bar.h"
|
||||||
#include "doc/layer.h"
|
#include "doc/layer.h"
|
||||||
|
#include "doc/layer_tilemap.h"
|
||||||
#include "doc/sprite.h"
|
#include "doc/sprite.h"
|
||||||
|
#include "doc/tilesets.h"
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "ui/alert.h"
|
#include "ui/alert.h"
|
||||||
#include "ui/widget.h"
|
#include "ui/widget.h"
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
|
// Calculates the list of unused tileset indexes (returned in tsiToDelete parameter)
|
||||||
|
// once the layers specified are removed.
|
||||||
|
// Also, if the UI is available, shows a warning message about the deletion of unused
|
||||||
|
// tilesets.
|
||||||
|
// This function returns true in any of the following:
|
||||||
|
// - There won't be deletion of tilesets, this means tsiToDelete is empty.
|
||||||
|
// - The user accepts continuing despite the warning.
|
||||||
|
// - There is no UI available.
|
||||||
|
static bool continue_deleting_unused_tilesets(
|
||||||
|
Context* ctx, Sprite* sprite, const LayerList layers,
|
||||||
|
std::set<tileset_index, std::greater<tileset_index>>& tsiToDelete)
|
||||||
|
{
|
||||||
|
std::vector<LayerTilemap*> tilemaps;
|
||||||
|
std::map<doc::tileset_index, int> timesSelected;
|
||||||
|
std::string layerNames;
|
||||||
|
for (auto layer : layers) {
|
||||||
|
if (layer->isTilemap()) {
|
||||||
|
auto tilemap = static_cast<LayerTilemap*>(layer);
|
||||||
|
timesSelected[tilemap->tilesetIndex()]++;
|
||||||
|
tilemaps.push_back(tilemap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto tilemap : tilemaps) {
|
||||||
|
auto ts = sprite->tilesets()->get(tilemap->tilesetIndex());
|
||||||
|
if (ts->tilemapsCount() == timesSelected[tilemap->tilesetIndex()]) {
|
||||||
|
tsiToDelete.insert(tilemap->tilesetIndex());
|
||||||
|
layerNames += tilemap->name() + ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_UI
|
||||||
|
// Just continue if UI is not available.
|
||||||
|
if (!ctx->isUIAvailable())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Remove last ", "
|
||||||
|
if (!layerNames.empty()) {
|
||||||
|
layerNames = layerNames.substr(0, layerNames.length() - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string message;
|
||||||
|
if (tsiToDelete.size() >= 1)
|
||||||
|
message = fmt::format(Strings::alerts_deleting_tilemaps_will_delete_tilesets(), layerNames);
|
||||||
|
|
||||||
|
return tsiToDelete.empty() ||
|
||||||
|
app::OptionalAlert::show(
|
||||||
|
Preferences::instance().tilemap.showDeleteUnusedTilesetAlert, 1, message) == 1;
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
class RemoveLayerCommand : public Command {
|
class RemoveLayerCommand : public Command {
|
||||||
public:
|
public:
|
||||||
RemoveLayerCommand();
|
RemoveLayerCommand();
|
||||||
@ -55,6 +112,11 @@ void RemoveLayerCommand::onExecute(Context* context)
|
|||||||
{
|
{
|
||||||
Tx tx(writer.context(), "Remove Layer");
|
Tx tx(writer.context(), "Remove Layer");
|
||||||
DocApi api = document->getApi(tx);
|
DocApi api = document->getApi(tx);
|
||||||
|
// We need to remove all the tilesets after the tilemaps are deleted
|
||||||
|
// and in descending tileset index order, otherwise the tileset indexes
|
||||||
|
// get mixed up. This is the reason we use a tileset_index set with
|
||||||
|
// the std::greater Compare.
|
||||||
|
std::set<tileset_index, std::greater<tileset_index>> tsiToDelete;
|
||||||
|
|
||||||
const Site* site = writer.site();
|
const Site* site = writer.site();
|
||||||
if (site->inTimeline() &&
|
if (site->inTimeline() &&
|
||||||
@ -73,6 +135,10 @@ void RemoveLayerCommand::onExecute(Context* context)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!continue_deleting_unused_tilesets(context, sprite, selLayers.toAllTilemaps(), tsiToDelete)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (Layer* layer : selLayers) {
|
for (Layer* layer : selLayers) {
|
||||||
api.removeLayer(layer);
|
api.removeLayer(layer);
|
||||||
}
|
}
|
||||||
@ -84,10 +150,20 @@ void RemoveLayerCommand::onExecute(Context* context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Layer* layer = writer.layer();
|
Layer* layer = writer.layer();
|
||||||
|
if (layer->isTilemap() && !continue_deleting_unused_tilesets(context, sprite, {layer}, tsiToDelete)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
layerName = layer->name();
|
layerName = layer->name();
|
||||||
api.removeLayer(layer);
|
api.removeLayer(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!tsiToDelete.empty()) {
|
||||||
|
for (tileset_index tsi : tsiToDelete) {
|
||||||
|
tx(new cmd::RemoveTileset(sprite, tsi));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tx.commit();
|
tx.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,6 +529,17 @@ void LayerGroup::allBrowsableLayers(LayerList& list) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LayerGroup::allTilemaps(LayerList& list) const
|
||||||
|
{
|
||||||
|
for (Layer* child : m_layers) {
|
||||||
|
if (child->isGroup())
|
||||||
|
static_cast<LayerGroup*>(child)->allTilemaps(list);
|
||||||
|
|
||||||
|
if (child->isTilemap())
|
||||||
|
list.push_back(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LayerGroup::getCels(CelList& cels) const
|
void LayerGroup::getCels(CelList& cels) const
|
||||||
{
|
{
|
||||||
for (const Layer* layer : m_layers)
|
for (const Layer* layer : m_layers)
|
||||||
|
@ -211,6 +211,7 @@ namespace doc {
|
|||||||
void allVisibleLayers(LayerList& list) const;
|
void allVisibleLayers(LayerList& list) const;
|
||||||
void allVisibleReferenceLayers(LayerList& list) const;
|
void allVisibleReferenceLayers(LayerList& list) const;
|
||||||
void allBrowsableLayers(LayerList& list) const;
|
void allBrowsableLayers(LayerList& list) const;
|
||||||
|
void allTilemaps(LayerList& list) const;
|
||||||
|
|
||||||
void getCels(CelList& cels) const override;
|
void getCels(CelList& cels) const override;
|
||||||
void displaceFrames(frame_t fromThis, frame_t delta) override;
|
void displaceFrames(frame_t fromThis, frame_t delta) override;
|
||||||
|
@ -99,6 +99,24 @@ LayerList SelectedLayers::toBrowsableLayerList() const
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LayerList SelectedLayers::toAllTilemaps() const
|
||||||
|
{
|
||||||
|
LayerList output;
|
||||||
|
|
||||||
|
if (empty())
|
||||||
|
return output;
|
||||||
|
|
||||||
|
for (Layer* layer : *this) {
|
||||||
|
if (layer->isGroup()) {
|
||||||
|
auto group = static_cast<LayerGroup*>(layer);
|
||||||
|
group->allTilemaps(output);
|
||||||
|
} else if (layer->isTilemap())
|
||||||
|
output.push_back(layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
void SelectedLayers::removeChildrenIfParentIsSelected()
|
void SelectedLayers::removeChildrenIfParentIsSelected()
|
||||||
{
|
{
|
||||||
SelectedLayers removeThese;
|
SelectedLayers removeThese;
|
||||||
|
@ -41,6 +41,7 @@ namespace doc {
|
|||||||
bool hasSameParent() const;
|
bool hasSameParent() const;
|
||||||
LayerList toBrowsableLayerList() const;
|
LayerList toBrowsableLayerList() const;
|
||||||
LayerList toAllLayersList() const;
|
LayerList toAllLayersList() const;
|
||||||
|
LayerList toAllTilemaps() const;
|
||||||
|
|
||||||
void removeChildrenIfParentIsSelected();
|
void removeChildrenIfParentIsSelected();
|
||||||
void expandCollapsedGroups();
|
void expandCollapsedGroups();
|
||||||
|
@ -736,6 +736,13 @@ LayerList Sprite::allBrowsableLayers() const
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LayerList Sprite::allTilemaps() const
|
||||||
|
{
|
||||||
|
LayerList list;
|
||||||
|
m_root->allTilemaps(list);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
CelsRange Sprite::cels() const
|
CelsRange Sprite::cels() const
|
||||||
{
|
{
|
||||||
SelectedFrames selFrames;
|
SelectedFrames selFrames;
|
||||||
|
@ -209,6 +209,7 @@ namespace doc {
|
|||||||
LayerList allVisibleLayers() const;
|
LayerList allVisibleLayers() const;
|
||||||
LayerList allVisibleReferenceLayers() const;
|
LayerList allVisibleReferenceLayers() const;
|
||||||
LayerList allBrowsableLayers() const;
|
LayerList allBrowsableLayers() const;
|
||||||
|
LayerList allTilemaps() const;
|
||||||
|
|
||||||
CelsRange cels() const;
|
CelsRange cels() const;
|
||||||
CelsRange cels(frame_t frame) const;
|
CelsRange cels(frame_t frame) const;
|
||||||
|
@ -10,6 +10,9 @@
|
|||||||
|
|
||||||
#include "doc/tileset.h"
|
#include "doc/tileset.h"
|
||||||
|
|
||||||
|
#include "doc/tilesets.h"
|
||||||
|
#include "doc/layer.h"
|
||||||
|
#include "doc/layer_tilemap.h"
|
||||||
#include "base/mem_utils.h"
|
#include "base/mem_utils.h"
|
||||||
#include "doc/primitives.h"
|
#include "doc/primitives.h"
|
||||||
#include "doc/remap.h"
|
#include "doc/remap.h"
|
||||||
@ -406,4 +409,15 @@ TilesetHashTable& Tileset::hashTable()
|
|||||||
return m_hash;
|
return m_hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Tileset::tilemapsCount() const {
|
||||||
|
auto tsi = sprite()->tilesets()->getIndex(this);
|
||||||
|
int count = 0;
|
||||||
|
for (auto layer : sprite()->allLayers()) {
|
||||||
|
if (layer->isTilemap() && static_cast<LayerTilemap*>(layer)->tilesetIndex() == tsi) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace doc
|
} // namespace doc
|
||||||
|
@ -131,6 +131,9 @@ namespace doc {
|
|||||||
// have to regenerate the empty tile with that new mask color.
|
// have to regenerate the empty tile with that new mask color.
|
||||||
void notifyRegenerateEmptyTile();
|
void notifyRegenerateEmptyTile();
|
||||||
|
|
||||||
|
// Returns the number of tilemap layers that are referencing this tileset.
|
||||||
|
int tilemapsCount() const;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
void assertValidHashTable();
|
void assertValidHashTable();
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#define DOC_TILESETS_H_INCLUDED
|
#define DOC_TILESETS_H_INCLUDED
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "doc/layer_tilemap.h"
|
||||||
|
#include "doc/sprite.h"
|
||||||
#include "doc/tileset.h"
|
#include "doc/tileset.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -40,7 +42,7 @@ namespace doc {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
tileset_index getIndex(Tileset *tileset) {
|
tileset_index getIndex(const Tileset *tileset) {
|
||||||
for (tileset_index i = 0; i < size(); ++i) {
|
for (tileset_index i = 0; i < size(); ++i) {
|
||||||
if (m_tilesets[i] == tileset) {
|
if (m_tilesets[i] == tileset) {
|
||||||
return i;
|
return i;
|
||||||
@ -55,23 +57,44 @@ namespace doc {
|
|||||||
m_tilesets[tsi] = tileset;
|
m_tilesets[tsi] = tileset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add(const tileset_index tsi, Tileset* tileset) {
|
||||||
|
if (tsi >= m_tilesets.size()) {
|
||||||
|
m_tilesets.push_back(tileset);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_tilesets.insert(m_tilesets.begin()+tsi, tileset);
|
||||||
|
// Update tileset indexes of the affected tilemaps. We have to shift the indexes
|
||||||
|
// for all the tilemaps pointing to a tileset index equals or greater than the added one.
|
||||||
|
shiftTilesetIndexes(tileset->sprite(), tsi, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void erase(const tileset_index tsi) {
|
void erase(const tileset_index tsi) {
|
||||||
// Do not m_tilesets.erase() the tileset so other tilesets
|
// When tsi is the last one, other tilemaps tilesets
|
||||||
// indexes/IDs are kept intact.
|
// indexes are not affected.
|
||||||
if (tsi == size()-1) {
|
if (tsi == size()-1) {
|
||||||
m_tilesets.erase(--m_tilesets.end());
|
m_tilesets.erase(--m_tilesets.end());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO Should we keep the empty slot? Or should we update all
|
auto ts = m_tilesets[tsi];
|
||||||
// indexes (even from external files?). Having a nullptr
|
m_tilesets.erase(m_tilesets.begin()+tsi);
|
||||||
// tileset in the sprite adds a lot of complexity (each
|
// Update tileset indexes of the affected tilemaps. We have to shift the indexes
|
||||||
// for-loop must check the tileset)
|
// for all the tilemaps pointing to a tileset index greater than the deleted one.
|
||||||
m_tilesets[tsi] = nullptr;
|
shiftTilesetIndexes(ts->sprite(), tsi+1, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Array m_tilesets;
|
Array m_tilesets;
|
||||||
|
|
||||||
|
void shiftTilesetIndexes(Sprite *sprite, tileset_index pos, int n) {
|
||||||
|
for (auto layer : sprite->allTilemaps()) {
|
||||||
|
auto tilemap = static_cast<LayerTilemap*>(layer);
|
||||||
|
if (tilemap->tilesetIndex() >= pos) {
|
||||||
|
tilemap->setTilesetIndex(tilemap->tilesetIndex()+n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace doc
|
} // namespace doc
|
||||||
|
@ -1117,3 +1117,113 @@ do
|
|||||||
expect_eq(app.activeLayer.cels[1].image.width, 1) -- width in tilemap terms
|
expect_eq(app.activeLayer.cels[1].image.width, 1) -- width in tilemap terms
|
||||||
expect_eq(app.activeLayer.cels[1].image.height, 2) -- height in tilemap terms
|
expect_eq(app.activeLayer.cels[1].image.height, 2) -- height in tilemap terms
|
||||||
end
|
end
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
-- Tests removal of unused tilesets when deleting tilemaps
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
do
|
||||||
|
local spr = Sprite(32, 32, ColorMode.INDEXED)
|
||||||
|
assert(spr.layers[1].isImage)
|
||||||
|
assert(not spr.layers[1].isTilemap)
|
||||||
|
|
||||||
|
-- Create some tilemaps
|
||||||
|
app.command.NewLayer{ tilemap=true }
|
||||||
|
assert(#spr.layers == 2)
|
||||||
|
local tilemapLay1 = spr.layers[2]
|
||||||
|
assert(tilemapLay1.isImage)
|
||||||
|
assert(tilemapLay1.isTilemap)
|
||||||
|
assert(#spr.tilesets == 1)
|
||||||
|
assert(spr.tilesets[1] == tilemapLay1.tileset)
|
||||||
|
|
||||||
|
app.command.NewLayer{ tilemap=true }
|
||||||
|
assert(#spr.layers == 3)
|
||||||
|
local tilemapLay2 = spr.layers[3]
|
||||||
|
assert(tilemapLay2.isImage)
|
||||||
|
assert(tilemapLay2.isTilemap)
|
||||||
|
assert(#spr.tilesets == 2)
|
||||||
|
assert(spr.tilesets[2] == tilemapLay2.tileset)
|
||||||
|
|
||||||
|
app.command.NewLayer{ tilemap=true }
|
||||||
|
assert(#spr.layers == 4)
|
||||||
|
local tilemapLay3 = spr.layers[4]
|
||||||
|
assert(tilemapLay3.isImage)
|
||||||
|
assert(tilemapLay3.isTilemap)
|
||||||
|
assert(#spr.tilesets == 3)
|
||||||
|
assert(spr.tilesets[3] == tilemapLay3.tileset)
|
||||||
|
|
||||||
|
-- Remove tilemap 2 and check that a tilemap was removed and
|
||||||
|
-- tilesets of remaining tilemaps are correct.
|
||||||
|
app.range.layers = { tilemapLay2 }
|
||||||
|
app.command.RemoveLayer()
|
||||||
|
assert(#spr.layers == 3)
|
||||||
|
assert(#spr.tilesets == 2)
|
||||||
|
assert(spr.tilesets[1] == tilemapLay1.tileset)
|
||||||
|
assert(spr.tilesets[2] == tilemapLay3.tileset)
|
||||||
|
|
||||||
|
-- Undo tilemap removal and check that it goes back to
|
||||||
|
-- previous state.
|
||||||
|
app.undo()
|
||||||
|
|
||||||
|
assert(#spr.layers == 4)
|
||||||
|
assert(#spr.tilesets == 3)
|
||||||
|
assert(spr.tilesets[1] == tilemapLay1.tileset)
|
||||||
|
assert(spr.tilesets[2] == tilemapLay2.tileset)
|
||||||
|
assert(spr.tilesets[3] == tilemapLay3.tileset)
|
||||||
|
|
||||||
|
-- Try removing 2 tilemaps now
|
||||||
|
app.range.layers = { tilemapLay1, tilemapLay2 }
|
||||||
|
app.command.RemoveLayer()
|
||||||
|
assert(#spr.layers == 2)
|
||||||
|
assert(#spr.tilesets == 1)
|
||||||
|
assert(spr.tilesets[1] == tilemapLay3.tileset)
|
||||||
|
|
||||||
|
app.undo()
|
||||||
|
|
||||||
|
assert(#spr.layers == 4)
|
||||||
|
assert(#spr.tilesets == 3)
|
||||||
|
assert(spr.tilesets[1] == tilemapLay1.tileset)
|
||||||
|
assert(spr.tilesets[2] == tilemapLay2.tileset)
|
||||||
|
assert(spr.tilesets[3] == tilemapLay3.tileset)
|
||||||
|
|
||||||
|
-- Assign same tileset to tilemap 1 and tilemap 3.
|
||||||
|
local oldTilemapLay3Tileset = tilemapLay3.tileset
|
||||||
|
tilemapLay3.tileset = tilemapLay1.tileset
|
||||||
|
-- We have to manually delete tilemap 3 tileset because
|
||||||
|
-- assigning a different tileset doesn't check for/remove
|
||||||
|
-- unused tilesets (TODO: should we add this?)
|
||||||
|
spr:deleteTileset(oldTilemapLay3Tileset)
|
||||||
|
|
||||||
|
assert(#spr.tilesets == 2)
|
||||||
|
assert(spr.tilesets[1] == tilemapLay1.tileset)
|
||||||
|
assert(spr.tilesets[2] == tilemapLay2.tileset)
|
||||||
|
assert(spr.tilesets[1] == tilemapLay3.tileset)
|
||||||
|
|
||||||
|
-- Remove tilemap 1 and check that no tileset was removed.
|
||||||
|
app.range.layers = { tilemapLay1 }
|
||||||
|
app.command.RemoveLayer()
|
||||||
|
assert(#spr.layers == 3)
|
||||||
|
assert(#spr.tilesets == 2)
|
||||||
|
assert(spr.tilesets[2] == tilemapLay2.tileset)
|
||||||
|
assert(spr.tilesets[1] == tilemapLay3.tileset)
|
||||||
|
|
||||||
|
-- Remove tilemap 3 and check that the tileset was removed now.
|
||||||
|
app.range.layers = { tilemapLay3 }
|
||||||
|
app.command.RemoveLayer()
|
||||||
|
assert(#spr.layers == 2)
|
||||||
|
assert(#spr.tilesets == 1)
|
||||||
|
assert(spr.tilesets[1] == tilemapLay2.tileset)
|
||||||
|
|
||||||
|
-- Undo all
|
||||||
|
app.undo()
|
||||||
|
app.undo()
|
||||||
|
app.undo()
|
||||||
|
-- Manually re-assign its tileset to tilemap 3.
|
||||||
|
tilemapLay3.tileset = spr.tilesets[3]
|
||||||
|
|
||||||
|
assert(#spr.layers == 4)
|
||||||
|
assert(#spr.tilesets == 3)
|
||||||
|
assert(spr.tilesets[1] == tilemapLay1.tileset)
|
||||||
|
assert(spr.tilesets[2] == tilemapLay2.tileset)
|
||||||
|
assert(spr.tilesets[3] == tilemapLay3.tileset)
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user