mirror of
https://github.com/aseprite/aseprite.git
synced 2024-11-20 14:21:45 +00:00
Add user data to tiles (fix #3626)
Co-authored-by: David Capello <david@igara.com>
This commit is contained in:
parent
ea17eae524
commit
6d6dfb96a9
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2022 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -20,12 +20,14 @@ namespace app {
|
||||
namespace cmd {
|
||||
|
||||
AddTile::AddTile(doc::Tileset* tileset,
|
||||
const doc::ImageRef& image)
|
||||
const doc::ImageRef& image,
|
||||
const doc::UserData& userData)
|
||||
: WithTileset(tileset)
|
||||
, WithImage(image.get())
|
||||
, m_size(0)
|
||||
, m_tileIndex(doc::notile)
|
||||
, m_imageRef(image)
|
||||
, m_userData(userData)
|
||||
{
|
||||
}
|
||||
|
||||
@ -36,6 +38,7 @@ AddTile::AddTile(doc::Tileset* tileset,
|
||||
, m_size(0)
|
||||
, m_tileIndex(ti)
|
||||
, m_imageRef(nullptr)
|
||||
, m_userData(tileset->getTileData(ti))
|
||||
{
|
||||
}
|
||||
|
||||
@ -51,7 +54,7 @@ void AddTile::onExecute()
|
||||
}
|
||||
else {
|
||||
ASSERT(m_imageRef);
|
||||
addTile(tileset, m_imageRef);
|
||||
addTile(tileset, m_imageRef, m_userData);
|
||||
m_imageRef.reset();
|
||||
}
|
||||
}
|
||||
@ -78,7 +81,7 @@ void AddTile::onRedo()
|
||||
m_imageRef.reset(read_image(m_stream));
|
||||
ASSERT(m_imageRef);
|
||||
|
||||
addTile(tileset, m_imageRef);
|
||||
addTile(tileset, m_imageRef, m_userData);
|
||||
m_imageRef.reset();
|
||||
|
||||
m_stream.str(std::string());
|
||||
@ -95,12 +98,14 @@ void AddTile::onFireNotifications()
|
||||
->notifyTilesetChanged(tileset);
|
||||
}
|
||||
|
||||
void AddTile::addTile(doc::Tileset* tileset, const doc::ImageRef& image)
|
||||
void AddTile::addTile(doc::Tileset* tileset,
|
||||
const doc::ImageRef& image,
|
||||
const doc::UserData& userData)
|
||||
{
|
||||
if (m_tileIndex == doc::notile)
|
||||
m_tileIndex = tileset->add(image);
|
||||
m_tileIndex = tileset->add(image, userData);
|
||||
else
|
||||
tileset->insert(m_tileIndex, image);
|
||||
tileset->insert(m_tileIndex, image, userData);
|
||||
|
||||
tileset->sprite()->incrementVersion();
|
||||
tileset->incrementVersion();
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2022 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -13,6 +13,7 @@
|
||||
#include "app/cmd/with_tileset.h"
|
||||
#include "doc/image_ref.h"
|
||||
#include "doc/tile.h"
|
||||
#include "doc/user_data.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
@ -27,8 +28,11 @@ namespace cmd {
|
||||
, public WithTileset
|
||||
, public WithImage {
|
||||
public:
|
||||
AddTile(doc::Tileset* tileset, const doc::ImageRef& image);
|
||||
AddTile(doc::Tileset* tileset, const doc::tile_index ti);
|
||||
AddTile(doc::Tileset* tileset,
|
||||
const doc::ImageRef& image,
|
||||
const doc::UserData& userData = UserData());
|
||||
AddTile(doc::Tileset* tileset,
|
||||
const doc::tile_index ti);
|
||||
|
||||
doc::tile_index tileIndex() const { return m_tileIndex; }
|
||||
|
||||
@ -38,17 +42,20 @@ namespace cmd {
|
||||
void onRedo() override;
|
||||
void onFireNotifications() override;
|
||||
size_t onMemSize() const override {
|
||||
// TODO add m_userData size
|
||||
return sizeof(*this) + m_size;
|
||||
}
|
||||
|
||||
private:
|
||||
void addTile(doc::Tileset* tileset,
|
||||
const doc::ImageRef& image);
|
||||
const doc::ImageRef& image,
|
||||
const doc::UserData& userData);
|
||||
|
||||
size_t m_size;
|
||||
std::stringstream m_stream;
|
||||
doc::tile_index m_tileIndex;
|
||||
doc::ImageRef m_imageRef;
|
||||
doc::UserData m_userData;
|
||||
};
|
||||
|
||||
} // namespace cmd
|
||||
|
@ -138,6 +138,7 @@ protected:
|
||||
sprite()->rgbMap(0))); // TODO first frame?
|
||||
|
||||
newTileset->set(idx, newTileImg);
|
||||
newTileset->setTileData(idx, tileset->getTileData(idx));
|
||||
}
|
||||
|
||||
jobProgress((float)progress / img_count);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -889,14 +889,17 @@ void copy_tiles_in_tileset(
|
||||
OPS_TRACE("copy_tiles_in_tileset beforeIndex=%d npicks=%d\n", beforeIndex, picks.picks());
|
||||
|
||||
std::vector<ImageRef> newTiles;
|
||||
std::vector<UserData> newDatas;
|
||||
for (int i=0; i<picks.size(); ++i) {
|
||||
if (!picks[i])
|
||||
continue;
|
||||
else if (i >= 0 && i < tileset->size()) {
|
||||
newTiles.emplace_back(Image::createCopy(tileset->get(i).get()));
|
||||
newDatas.emplace_back(tileset->getTileData(i));
|
||||
}
|
||||
else {
|
||||
newTiles.emplace_back(tileset->makeEmptyTile());
|
||||
newDatas.emplace_back(UserData());
|
||||
}
|
||||
}
|
||||
|
||||
@ -921,8 +924,8 @@ void copy_tiles_in_tileset(
|
||||
// "beforeIndex" with empty tiles
|
||||
while (tileset->size() < i)
|
||||
cmds->executeAndAdd(new cmd::AddTile(tileset, tileset->makeEmptyTile()));
|
||||
|
||||
tileset->insert(i, newTiles[j++]);
|
||||
tileset->insert(i, newTiles[j], newDatas[j]);
|
||||
j++;
|
||||
cmds->executeAndAdd(new cmd::AddTile(tileset, i));
|
||||
}
|
||||
}
|
||||
|
@ -752,7 +752,7 @@ void ExpandCelCanvas::copySourceTilestToDestTileset()
|
||||
for (tile_index i=0; i<srcTileset->size(); ++i) {
|
||||
doc::copy_image(m_dstTileset->get(i).get(),
|
||||
srcTileset->get(i).get());
|
||||
|
||||
m_dstTileset->setTileData(i, srcTileset->getTileData(i));
|
||||
// To rehash the tileset
|
||||
m_dstTileset->notifyTileContentChange(i);
|
||||
}
|
||||
|
@ -534,8 +534,10 @@ void Sprite::replaceImage(ObjectId curImageId, const ImageRef& newImage)
|
||||
for (Tileset* tileset : *tilesets()) {
|
||||
for (tile_index i=0; i<tileset->size(); ++i) {
|
||||
ImageRef image = tileset->get(i);
|
||||
if (image && image->id() == curImageId)
|
||||
if (image && image->id() == curImageId) {
|
||||
// Change only the tile image (not its user data)
|
||||
tileset->set(i, newImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ Tileset::Tileset(Sprite* sprite,
|
||||
, m_sprite(sprite)
|
||||
, m_grid(grid)
|
||||
, m_tiles(ntiles)
|
||||
, m_datas(ntiles)
|
||||
{
|
||||
// The origin of tileset grids must be 0,0 (the origin is then
|
||||
// specified by each cel position)
|
||||
@ -64,6 +65,7 @@ Tileset* Tileset::MakeCopyWithSameImages(const Tileset* tileset)
|
||||
ImageRef image = tileset->get(ti);
|
||||
ASSERT(image);
|
||||
copy->set(ti, image);
|
||||
copy->setTileData(ti, tileset->getTileData(ti));
|
||||
}
|
||||
return copy.release();
|
||||
}
|
||||
@ -77,6 +79,7 @@ Tileset* Tileset::MakeCopyCopyingImages(const Tileset* tileset)
|
||||
ASSERT(image);
|
||||
// TODO can we avoid making a copy of this image
|
||||
copy->set(ti, ImageRef(Image::createCopy(image.get())));
|
||||
copy->setTileData(ti, tileset->getTileData(ti));
|
||||
}
|
||||
return copy.release();
|
||||
}
|
||||
@ -95,6 +98,7 @@ void Tileset::resize(const tile_index ntiles)
|
||||
{
|
||||
int oldSize = m_tiles.size();
|
||||
m_tiles.resize(ntiles);
|
||||
m_datas.resize(ntiles);
|
||||
for (tile_index ti=oldSize; ti<ntiles; ++ti)
|
||||
m_tiles[ti] = makeEmptyTile();
|
||||
}
|
||||
@ -102,6 +106,7 @@ void Tileset::resize(const tile_index ntiles)
|
||||
void Tileset::remap(const Remap& remap)
|
||||
{
|
||||
Tiles tmp = m_tiles;
|
||||
Datas tmpUD = m_datas;
|
||||
|
||||
// The notile cannot be remapped
|
||||
ASSERT(remap[0] == 0);
|
||||
@ -116,12 +121,19 @@ void Tileset::remap(const Remap& remap)
|
||||
ASSERT(remap[ti] != notile);
|
||||
|
||||
m_tiles[remap[ti]] = tmp[ti];
|
||||
m_datas[remap[ti]] = tmpUD[ti];
|
||||
}
|
||||
}
|
||||
|
||||
rehash();
|
||||
}
|
||||
|
||||
void Tileset::setTileData(const tile_index ti,
|
||||
const UserData& userData)
|
||||
{
|
||||
m_datas[ti] = userData;
|
||||
}
|
||||
|
||||
void Tileset::set(const tile_index ti,
|
||||
const ImageRef& image)
|
||||
{
|
||||
@ -144,7 +156,8 @@ void Tileset::set(const tile_index ti,
|
||||
hashImage(ti, image);
|
||||
}
|
||||
|
||||
tile_index Tileset::add(const ImageRef& image)
|
||||
tile_index Tileset::add(const ImageRef& image,
|
||||
const UserData& userData)
|
||||
{
|
||||
ASSERT(image);
|
||||
ASSERT(image->width() == m_grid.tileSize().w);
|
||||
@ -152,6 +165,7 @@ tile_index Tileset::add(const ImageRef& image)
|
||||
|
||||
preprocess_transparent_pixels(image.get());
|
||||
m_tiles.push_back(image);
|
||||
m_datas.push_back(userData);
|
||||
|
||||
const tile_index newIndex = tile_index(m_tiles.size()-1);
|
||||
if (!m_hash.empty())
|
||||
@ -160,7 +174,8 @@ tile_index Tileset::add(const ImageRef& image)
|
||||
}
|
||||
|
||||
void Tileset::insert(const tile_index ti,
|
||||
const ImageRef& image)
|
||||
const ImageRef& image,
|
||||
const UserData& userData)
|
||||
{
|
||||
ASSERT(image);
|
||||
ASSERT(image->width() == m_grid.tileSize().w);
|
||||
@ -175,6 +190,7 @@ void Tileset::insert(const tile_index ti,
|
||||
ASSERT(ti >= 0 && ti <= m_tiles.size()+1);
|
||||
preprocess_transparent_pixels(image.get());
|
||||
m_tiles.insert(m_tiles.begin()+ti, image);
|
||||
m_datas.insert(m_datas.begin()+ti, userData);
|
||||
|
||||
if (!m_hash.empty()) {
|
||||
// Fix all indexes in the hash that are greater than "ti"
|
||||
@ -194,6 +210,7 @@ void Tileset::erase(const tile_index ti)
|
||||
//removeFromHash(ti, true);
|
||||
|
||||
m_tiles.erase(m_tiles.begin()+ti);
|
||||
m_datas.erase(m_datas.begin()+ti);
|
||||
rehash();
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ namespace doc {
|
||||
class Tileset : public WithUserData {
|
||||
public:
|
||||
typedef std::vector<ImageRef> Tiles;
|
||||
typedef std::vector<UserData> Datas;
|
||||
typedef Tiles::iterator iterator;
|
||||
typedef Tiles::const_iterator const_iterator;
|
||||
|
||||
@ -68,9 +69,20 @@ namespace doc {
|
||||
void set(const tile_index ti,
|
||||
const ImageRef& image);
|
||||
|
||||
tile_index add(const ImageRef& image);
|
||||
UserData getTileData(const tile_index ti) const {
|
||||
if (ti >= 0 && ti < size())
|
||||
return m_datas[ti];
|
||||
else
|
||||
return UserData();
|
||||
}
|
||||
void setTileData(const tile_index ti,
|
||||
const UserData& userData);
|
||||
|
||||
tile_index add(const ImageRef& image,
|
||||
const UserData& userData = UserData());
|
||||
void insert(const tile_index ti,
|
||||
const ImageRef& image);
|
||||
const ImageRef& image,
|
||||
const UserData& userData = UserData());
|
||||
void erase(const tile_index ti);
|
||||
|
||||
// Linked with an external file
|
||||
@ -126,6 +138,7 @@ namespace doc {
|
||||
Sprite* m_sprite;
|
||||
Grid m_grid;
|
||||
Tiles m_tiles;
|
||||
Datas m_datas;
|
||||
TilesetHashTable m_hash;
|
||||
std::string m_name;
|
||||
int m_baseIndex = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user