Add metatile swap

This commit is contained in:
GriffinR
2025-07-29 16:45:31 -04:00
parent f6f07ca5fc
commit d0337a7ae3
19 changed files with 504 additions and 177 deletions

View File

@@ -25,6 +25,7 @@ public:
if (head > 0) {
return history.at(--head);
}
head = -1;
return NULL;
}
@@ -37,9 +38,7 @@ public:
void push(T commit) {
while (head + 1 < history.length()) {
T item = history.last();
history.removeLast();
delete item;
delete history.takeLast();
}
if (saved > head) {
saved = -1;
@@ -48,7 +47,7 @@ public:
head++;
}
T current() {
T current() const {
if (head < 0 || history.length() == 0) {
return NULL;
}
@@ -59,10 +58,30 @@ public:
saved = head;
}
bool isSaved() {
bool isSaved() const {
return saved == head;
}
int length() const {
return history.length();
}
bool isEmpty() const {
return history.isEmpty();
}
int index() const {
return head;
}
bool canUndo() const {
return head >= 0;
}
bool canRedo() const {
return (head + 1) < history.length();
}
private:
QList<T> history;
int head = -1;

View File

@@ -124,10 +124,13 @@ public:
bool isWithinBounds(const QRect &rect) const;
bool isWithinBorderBounds(int x, int y) const;
bool getBlock(int x, int y, Block *out);
bool getBlock(int x, int y, Block *out) const;
void setBlock(int x, int y, Block block, bool enableScriptCallback = false);
void setBlockdata(Blockdata blockdata, bool enableScriptCallback = false);
uint16_t getMetatileId(int x, int y) const;
bool setMetatileId(int x, int y, uint16_t metatileId, bool enableScriptCallback = false);
void adjustDimensions(const QMargins &margins, bool setNewBlockdata = true);
void setDimensions(int newWidth, int newHeight, bool setNewBlockdata = true);
void setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false);

View File

@@ -109,6 +109,7 @@ public:
QStringList secondaryTilesetLabels;
QStringList tilesetLabelsOrdered;
QSet<QString> getPairedTilesetLabels(const Tileset *tileset) const;
QSet<QString> getTilesetLayoutIds(const Tileset *priamryTileset, const Tileset *secondaryTileset) const;
bool readMapGroups();
void addNewMapGroup(const QString &groupName);

View File

@@ -44,7 +44,7 @@ private:
Tileset *secondaryTileset;
QList<ColorInputWidget*> colorInputs;
QList<History<PaletteHistoryItem*>> palettesHistory;
QMap<int, History<PaletteHistoryItem*>> palettesHistory;
QMap<int,QSet<int>> unusedColorCache;
QPointer<PaletteColorSearch> colorSearchWindow;
@@ -53,6 +53,7 @@ private:
void refreshPaletteId();
void commitEditHistory();
void commitEditHistory(int paletteId);
void updateEditHistoryActions();
void restoreWindowState();
void invalidateCache();
void closeEvent(QCloseEvent*);

View File

@@ -26,6 +26,8 @@ public:
virtual void setMaxSelectionSize(int width, int height);
QSize maxSelectionSize() { return QSize(this->maxSelectionWidth, this->maxSelectionHeight); }
void setSelectionStyle(Qt::PenStyle style);
protected:
int cellWidth;
int cellHeight;
@@ -40,10 +42,13 @@ protected:
void select(const QPoint &pos, const QSize &size = QSize(1,1));
void select(int x, int y, int width = 1, int height = 1) { select(QPoint(x, y), QSize(width, height)); }
void updateSelection(const QPoint &pos);
QPoint getCellPos(QPointF);
QPoint getCellPos(const QPointF &itemPos);
int getBoundedWidth(int width) const { return qBound(1, width, this->maxSelectionWidth); }
int getBoundedHeight(int height) const { return qBound(1, height, this->maxSelectionHeight); }
virtual void mousePressEvent(QGraphicsSceneMouseEvent*) override;
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent*) override;
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override;
virtual void drawSelectionRect(const QPoint &, const QSize &, Qt::PenStyle style = Qt::SolidLine);
virtual void drawSelection();
virtual int cellsWide() const { return this->cellWidth ? (pixmap().width() / this->cellWidth) : 0; }
virtual int cellsTall() const { return this->cellHeight ? (pixmap().height() / this->cellHeight) : 0; }
@@ -53,6 +58,9 @@ signals:
private:
QPoint prevCellPos = QPoint(-1,-1);
Qt::PenStyle selectionStyle = Qt::SolidLine;
void setSelection(const QPoint &pos, const QSize &size);
};
#endif // SELECTABLEPIXMAPITEM_H

View File

@@ -20,6 +20,7 @@ class TilesetEditor;
class MetatileHistoryItem {
public:
MetatileHistoryItem() {};
MetatileHistoryItem(uint16_t metatileId, Metatile *prevMetatile, Metatile *newMetatile, QString prevLabel, QString newLabel) {
this->metatileId = metatileId;
this->prevMetatile = prevMetatile;
@@ -27,15 +28,24 @@ public:
this->prevLabel = prevLabel;
this->newLabel = newLabel;
}
MetatileHistoryItem(uint16_t metatileIdA, uint16_t metatileIdB) {
this->metatileId = metatileIdA;
this->swapMetatileId = metatileIdB;
this->isSwap = true;
}
~MetatileHistoryItem() {
delete this->prevMetatile;
delete this->newMetatile;
}
uint16_t metatileId;
Metatile *prevMetatile;
Metatile *newMetatile;
uint16_t metatileId = 0;
Metatile *prevMetatile = nullptr;
Metatile *newMetatile = nullptr;
QString prevLabel;
QString newLabel;
uint16_t swapMetatileId = 0;
bool isSwap = false;
};
class TilesetEditor : public QMainWindow
@@ -122,8 +132,8 @@ private:
void countMetatileUsage();
void countTileUsage();
void copyMetatile(bool cut);
void pasteMetatile(const Metatile * toPaste, QString label);
bool replaceMetatile(uint16_t metatileId, const Metatile * src, QString label);
void pasteMetatile(const Metatile &toPaste, QString label);
bool replaceMetatile(uint16_t metatileId, const Metatile &src, QString label);
void commitMetatileChange(Metatile * prevMetatile);
void commitMetatileAndLabelChange(Metatile * prevMetatile, QString prevLabel);
uint32_t attributeNameToValue(Metatile::Attr attribute, const QString &text, bool *ok);
@@ -134,11 +144,17 @@ private:
void commitEncounterType();
void commitTerrainType();
void commitLayerType();
void commit(MetatileHistoryItem *item);
void updateEditHistoryActions();
void setRawAttributesVisible(bool visible);
void refreshTileFlips();
void refreshPaletteId();
void paintSelectedLayerTiles(const QPoint &pos, bool paletteOnly = false);
void setMetatileLayerOrientation(Qt::Orientation orientation);
void commitMetatileSwap(uint16_t metatileIdA, uint16_t metatileIdB);
bool swapMetatiles(uint16_t metatileIdA, uint16_t metatileIdB);
void applyMetatileSwapToLayouts(uint16_t metatileIdA, uint16_t metatileIdB);
void applyMetatileSwapsToLayouts();
Ui::TilesetEditor *ui;
History<MetatileHistoryItem*> metatileHistory;
@@ -162,6 +178,7 @@ private:
bool lockSelection = false;
QSet<uint16_t> metatileReloadQueue;
MetatileImageExporter::Settings *metatileImageExportSettings = nullptr;
QList<QPair<uint16_t,uint16_t>> metatileIdSwaps;
bool save();

View File

@@ -19,9 +19,13 @@ public:
bool select(uint16_t metatileId);
void setTilesets(Tileset*, Tileset*);
uint16_t getSelectedMetatileId() const { return this->selectedMetatileId; }
void updateSelectedMetatile();
QPoint getMetatileIdCoordsOnWidget(uint16_t metatileId) const;
void setSwapMode(bool enabeled);
void addToSwapSelection(uint16_t metatileId);
void removeFromSwapSelection(uint16_t metatileId);
void clearSwapSelection();
QVector<uint16_t> usedMetatiles;
bool selectorShowUnused = false;
bool selectorShowCounts = false;
@@ -42,11 +46,15 @@ private:
Tileset *primaryTileset = nullptr;
Tileset *secondaryTileset = nullptr;
uint16_t selectedMetatileId;
QList<uint16_t> swapMetatileIds;
bool inSwapMode = false;
void updateBasePixmap();
uint16_t posToMetatileId(int x, int y, bool *ok = nullptr) const;
uint16_t posToMetatileId(const QPoint &pos, bool *ok = nullptr) const;
QPoint metatileIdToPos(uint16_t metatileId, bool *ok = nullptr) const;
bool shouldAcceptEvent(QGraphicsSceneMouseEvent*);
bool isValidMetatileId(uint16_t metatileId) const;
int numRows(int numMetatiles) const;
int numRows() const;
void drawGrid();
@@ -60,6 +68,7 @@ signals:
void hoveredMetatileChanged(uint16_t);
void hoveredMetatileCleared();
void selectedMetatileChanged(uint16_t);
void swapRequested(uint16_t, uint16_t);
};
#endif // TILESETEDITORMETATILESELECTOR_H