diff --git a/src/nostalgia/core/studio/tilesheeteditor.cpp b/src/nostalgia/core/studio/tilesheeteditor.cpp index 9d68093b..02d1f480 100644 --- a/src/nostalgia/core/studio/tilesheeteditor.cpp +++ b/src/nostalgia/core/studio/tilesheeteditor.cpp @@ -348,17 +348,11 @@ class PasteClipboardCommand: public QUndoCommand { }; -void TileSheetClipboard::add(int idx, int color) { - if (m_chunks.size() && m_chunks.back().index + m_chunks.back().size == idx) { - ++m_chunks.back().size; - } else { - m_chunks.push_back({idx, 1}); - } +void TileSheetClipboard::addPixel(int color) { m_pixels.push_back(color); } void TileSheetClipboard::clear() { - m_chunks.clear(); m_pixels.clear(); } @@ -366,22 +360,17 @@ bool TileSheetClipboard::empty() const { return m_pixels.empty(); } -void TileSheetClipboard::paste(int targetIdx, QVector *pixels) const { - std::size_t ci = 0; // clipboard index - // set prevSrcIdx to current source index, as first iteration is already - // correct - int prevSrcIdx = m_chunks.size() ? m_chunks[0].index : 0; - for (std::size_t chunkIdx = 0; chunkIdx < m_chunks.size(); ++chunkIdx) { - const auto &chunk = m_chunks[chunkIdx]; - targetIdx += chunk.index - prevSrcIdx; - prevSrcIdx = chunk.index; - const auto targetMod = targetIdx - chunk.index; - for (int i = 0; i < chunk.size; ++i) { - const auto ti = chunk.index + i + targetMod; // target index - if (ti < pixels->size()) { - (*pixels)[ti] = m_pixels[ci]; +void TileSheetClipboard::pastePixels(common::Point pt, QVector *tgtPixels, int tgtColumns) const { + std::size_t srcIdx = 0; + const auto w = m_p2.x - m_p1.x; + const auto h = m_p2.y - m_p1.y; + for (int x = 0; x <= w; ++x) { + for (int y = 0; y <= h; ++y) { + const auto tgtIdx = ptToIdx(pt + common::Point(x, y), tgtColumns); + if (tgtIdx < tgtPixels->size()) { + (*tgtPixels)[tgtIdx] = m_pixels[srcIdx]; } - ++ci; + ++srcIdx; } } } @@ -616,18 +605,23 @@ void SheetData::cutToClipboard() { } void SheetData::cutToClipboard(TileSheetClipboard *cb) { - const auto start = ptToIdx(cb->point1(), m_columns); - const auto end = ptToIdx(cb->point2(), m_columns); + const auto pt1 = cb->point1(); + const auto pt2 = cb->point2(); auto apply = std::make_unique(); - for (int i = start; i <= end; ++i) { - const auto s = m_pixelSelected[i]; - if (s) { - cb->add(i, m_pixels[i]); - apply->add(i, 0); + for (int x = pt1.x; x <= pt2.x; ++x) { + for (int y = pt1.y; y <= pt2.y; ++y) { + const auto pt = common::Point(x, y); + const auto i = ptToIdx(pt, m_columns); + const auto s = m_pixelSelected[i]; + if (s) { + cb->addPixel(m_pixels[i]); + apply->addPixel(0); + } } } apply->setPoints(cb->point1(), cb->point2()); - m_cmdStack->push(new PasteClipboardCommand(this, std::make_unique(*cb), std::move(apply))); + auto restore = std::make_unique(*cb); + m_cmdStack->push(new PasteClipboardCommand(this, std::move(restore), std::move(apply))); } void SheetData::copyToClipboard() { @@ -636,12 +630,13 @@ void SheetData::copyToClipboard() { } void SheetData::copyToClipboard(TileSheetClipboard *cb) { - const auto start = ptToIdx(cb->point1(), m_columns); - const auto end = ptToIdx(cb->point2(), m_columns); - for (int i = start; i <= end; ++i) { - const auto s = m_pixelSelected[i]; - if (s) { - cb->add(i, m_pixels[i]); + const auto p1 = cb->point1(); + const auto p2 = cb->point2(); + for (int x = p1.x; x <= p2.x; ++x) { + for (int y = p1.y; y <= p2.y; ++y) { + const auto pt = common::Point(x, y); + const auto idx = ptToIdx(pt, m_columns); + cb->addPixel(m_pixels[idx]); } } } @@ -658,8 +653,7 @@ void SheetData::pasteClipboard() { } void SheetData::applyClipboard(const TileSheetClipboard &cb) { - const auto idx = ptToIdx(cb.point1(), m_columns); - cb.paste(idx, &m_pixels); + cb.pastePixels(cb.point1(), &m_pixels, m_columns); emit pixelsChanged(); emit changeOccurred(); } diff --git a/src/nostalgia/core/studio/tilesheeteditor.hpp b/src/nostalgia/core/studio/tilesheeteditor.hpp index 9a09d9a8..79576b08 100644 --- a/src/nostalgia/core/studio/tilesheeteditor.hpp +++ b/src/nostalgia/core/studio/tilesheeteditor.hpp @@ -51,40 +51,39 @@ struct PixelChunk { static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.studio.PixelChunk"; static constexpr auto Fields = 2; static constexpr auto TypeVersion = 1; - int index = -1; + common::Point pt; int size = 0; }; template ox::Error model(T *io, PixelChunk *c) { io->template setTypeInfo(); - oxReturnError(io->field("index", &c->index)); + oxReturnError(io->field("pt", &c->pt)); oxReturnError(io->field("size", &c->size)); return OxError(0); } struct TileSheetClipboard { static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.studio.TileSheetClipboard"; - static constexpr auto Fields = 2; + static constexpr auto Fields = 3; static constexpr auto TypeVersion = 1; template friend ox::Error model(T*, TileSheetClipboard*); protected: - std::vector m_chunks; std::vector m_pixels; common::Point m_p1; common::Point m_p2; public: - void add(int idx, int color); + void addPixel(int color); void clear(); [[nodiscard]] bool empty() const; - void paste(int targetIdx, QVector *pixels) const; + void pastePixels(common::Point pt, QVector *tgt, int tgtColumns) const; void setPoints(common::Point p1, common::Point p2); @@ -97,8 +96,9 @@ struct TileSheetClipboard { template ox::Error model(T *io, TileSheetClipboard *b) { io->template setTypeInfo(); - oxReturnError(io->field("chunks", &b->m_chunks)); oxReturnError(io->field("pixels", &b->m_pixels)); + oxReturnError(io->field("p1", &b->m_p1)); + oxReturnError(io->field("p2", &b->m_p2)); return OxError(0); }