Add edit-undo history to tileset metatile editing
This commit is contained in:
parent
888270f3ef
commit
e42c2e1a81
7 changed files with 149 additions and 14 deletions
|
@ -407,7 +407,15 @@
|
||||||
<addaction name="actionChange_Metatiles_Count"/>
|
<addaction name="actionChange_Metatiles_Count"/>
|
||||||
<addaction name="actionChange_Palettes"/>
|
<addaction name="actionChange_Palettes"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuEdit">
|
||||||
|
<property name="title">
|
||||||
|
<string>Edit</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionUndo"/>
|
||||||
|
<addaction name="actionRedo"/>
|
||||||
|
</widget>
|
||||||
<addaction name="menuFile"/>
|
<addaction name="menuFile"/>
|
||||||
|
<addaction name="menuEdit"/>
|
||||||
<addaction name="menuTools"/>
|
<addaction name="menuTools"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QStatusBar" name="statusbar"/>
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
|
@ -439,6 +447,22 @@
|
||||||
<string>Change Palettes</string>
|
<string>Change Palettes</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionUndo">
|
||||||
|
<property name="text">
|
||||||
|
<string>Undo</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+Z</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionRedo">
|
||||||
|
<property name="text">
|
||||||
|
<string>Redo</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+Y</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|
|
@ -14,6 +14,7 @@ public:
|
||||||
uint8_t layerType;
|
uint8_t layerType;
|
||||||
|
|
||||||
Metatile *copy();
|
Metatile *copy();
|
||||||
|
void copyInPlace(Metatile*);
|
||||||
static int getBlockIndex(int);
|
static int getBlockIndex(int);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,14 +13,18 @@ public:
|
||||||
this->metatile = metatile;
|
this->metatile = metatile;
|
||||||
this->primaryTileset = primaryTileset;
|
this->primaryTileset = primaryTileset;
|
||||||
this->secondaryTileset = secondaryTileset;
|
this->secondaryTileset = secondaryTileset;
|
||||||
|
this->clearLastModifiedCoords();
|
||||||
}
|
}
|
||||||
void draw();
|
void draw();
|
||||||
void setTilesets(Tileset*, Tileset*);
|
void setTilesets(Tileset*, Tileset*);
|
||||||
void setMetatile(Metatile*);
|
void setMetatile(Metatile*);
|
||||||
|
void clearLastModifiedCoords();
|
||||||
private:
|
private:
|
||||||
Metatile* metatile;
|
Metatile* metatile;
|
||||||
Tileset *primaryTileset;
|
Tileset *primaryTileset;
|
||||||
Tileset *secondaryTileset;
|
Tileset *secondaryTileset;
|
||||||
|
QPoint prevChangedTile;
|
||||||
|
void getBoundedCoords(QPointF, int*, int*);
|
||||||
signals:
|
signals:
|
||||||
void tileChanged(int, int);
|
void tileChanged(int, int);
|
||||||
void selectedTilesChanged(QPoint, int, int);
|
void selectedTilesChanged(QPoint, int, int);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
#include "history.h"
|
||||||
#include "paletteeditor.h"
|
#include "paletteeditor.h"
|
||||||
#include "tileseteditormetatileselector.h"
|
#include "tileseteditormetatileselector.h"
|
||||||
#include "tileseteditortileselector.h"
|
#include "tileseteditortileselector.h"
|
||||||
|
@ -12,6 +13,22 @@ namespace Ui {
|
||||||
class TilesetEditor;
|
class TilesetEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MetatileHistoryItem {
|
||||||
|
public:
|
||||||
|
MetatileHistoryItem(uint16_t metatileId, Metatile *prevMetatile, Metatile *newMetatile) {
|
||||||
|
this->metatileId = metatileId;
|
||||||
|
this->prevMetatile = prevMetatile;
|
||||||
|
this->newMetatile = newMetatile;
|
||||||
|
}
|
||||||
|
~MetatileHistoryItem() {
|
||||||
|
delete this->prevMetatile;
|
||||||
|
delete this->newMetatile;
|
||||||
|
}
|
||||||
|
uint16_t metatileId;
|
||||||
|
Metatile *prevMetatile;
|
||||||
|
Metatile *newMetatile;
|
||||||
|
};
|
||||||
|
|
||||||
class TilesetEditor : public QMainWindow
|
class TilesetEditor : public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -41,10 +58,6 @@ private slots:
|
||||||
|
|
||||||
void on_checkBox_yFlip_stateChanged(int arg1);
|
void on_checkBox_yFlip_stateChanged(int arg1);
|
||||||
|
|
||||||
void on_comboBox_metatileBehaviors_currentIndexChanged(const QString &arg1);
|
|
||||||
|
|
||||||
void on_comboBox_layerType_currentIndexChanged(int index);
|
|
||||||
|
|
||||||
void on_actionSave_Tileset_triggered();
|
void on_actionSave_Tileset_triggered();
|
||||||
|
|
||||||
void on_actionImport_Primary_Tiles_triggered();
|
void on_actionImport_Primary_Tiles_triggered();
|
||||||
|
@ -55,6 +68,14 @@ private slots:
|
||||||
|
|
||||||
void on_actionChange_Palettes_triggered();
|
void on_actionChange_Palettes_triggered();
|
||||||
|
|
||||||
|
void on_actionUndo_triggered();
|
||||||
|
|
||||||
|
void on_actionRedo_triggered();
|
||||||
|
|
||||||
|
void on_comboBox_metatileBehaviors_activated(const QString &arg1);
|
||||||
|
|
||||||
|
void on_comboBox_layerType_activated(int arg1);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void closeEvent(QCloseEvent*);
|
void closeEvent(QCloseEvent*);
|
||||||
void initMetatileSelector();
|
void initMetatileSelector();
|
||||||
|
@ -65,6 +86,7 @@ private:
|
||||||
void importTilesetTiles(Tileset*, bool);
|
void importTilesetTiles(Tileset*, bool);
|
||||||
void refresh();
|
void refresh();
|
||||||
Ui::TilesetEditor *ui;
|
Ui::TilesetEditor *ui;
|
||||||
|
History<MetatileHistoryItem*> metatileHistory;
|
||||||
TilesetEditorMetatileSelector *metatileSelector = nullptr;
|
TilesetEditorMetatileSelector *metatileSelector = nullptr;
|
||||||
TilesetEditorTileSelector *tileSelector = nullptr;
|
TilesetEditorTileSelector *tileSelector = nullptr;
|
||||||
MetatileLayersItem *metatileLayersItem = nullptr;
|
MetatileLayersItem *metatileLayersItem = nullptr;
|
||||||
|
|
|
@ -18,6 +18,14 @@ Metatile* Metatile::copy() {
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Metatile::copyInPlace(Metatile *other) {
|
||||||
|
this->behavior = other->behavior;
|
||||||
|
this->layerType = other->layerType;
|
||||||
|
for (int i = 0; i < this->tiles->length(); i++) {
|
||||||
|
(*this->tiles)[i] = other->tiles->at(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int Metatile::getBlockIndex(int index) {
|
int Metatile::getBlockIndex(int index) {
|
||||||
if (index < Project::getNumMetatilesPrimary()) {
|
if (index < Project::getNumMetatilesPrimary()) {
|
||||||
return index;
|
return index;
|
||||||
|
|
|
@ -29,12 +29,14 @@ void MetatileLayersItem::draw() {
|
||||||
|
|
||||||
void MetatileLayersItem::setMetatile(Metatile *metatile) {
|
void MetatileLayersItem::setMetatile(Metatile *metatile) {
|
||||||
this->metatile = metatile;
|
this->metatile = metatile;
|
||||||
|
this->clearLastModifiedCoords();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetatileLayersItem::setTilesets(Tileset *primaryTileset, Tileset *secondaryTileset) {
|
void MetatileLayersItem::setTilesets(Tileset *primaryTileset, Tileset *secondaryTileset) {
|
||||||
this->primaryTileset = primaryTileset;
|
this->primaryTileset = primaryTileset;
|
||||||
this->secondaryTileset = secondaryTileset;
|
this->secondaryTileset = secondaryTileset;
|
||||||
this->draw();
|
this->draw();
|
||||||
|
this->clearLastModifiedCoords();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetatileLayersItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
void MetatileLayersItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
|
@ -45,17 +47,17 @@ void MetatileLayersItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
emit this->selectedTilesChanged(selectionOrigin, dimensions.x(), dimensions.y());
|
emit this->selectedTilesChanged(selectionOrigin, dimensions.x(), dimensions.y());
|
||||||
this->drawSelection();
|
this->drawSelection();
|
||||||
} else {
|
} else {
|
||||||
QPointF pos = event->pos();
|
int x, y;
|
||||||
int x = static_cast<int>(pos.x()) / 16;
|
this->getBoundedCoords(event->pos(), &x, &y);
|
||||||
int y = static_cast<int>(pos.y()) / 16;
|
if (prevChangedTile.x() != x || prevChangedTile.y() != y) {
|
||||||
|
this->prevChangedTile.setX(x);
|
||||||
|
this->prevChangedTile.setY(y);
|
||||||
emit this->tileChanged(x, y);
|
emit this->tileChanged(x, y);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetatileLayersItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
|
void MetatileLayersItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
QPointF pos = event->pos();
|
|
||||||
int x = static_cast<int>(pos.x()) / 16;
|
|
||||||
int y = static_cast<int>(pos.y()) / 16;
|
|
||||||
if (event->buttons() & Qt::RightButton) {
|
if (event->buttons() & Qt::RightButton) {
|
||||||
SelectablePixmapItem::mouseMoveEvent(event);
|
SelectablePixmapItem::mouseMoveEvent(event);
|
||||||
QPoint selectionOrigin = this->getSelectionStart();
|
QPoint selectionOrigin = this->getSelectionStart();
|
||||||
|
@ -63,8 +65,14 @@ void MetatileLayersItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
emit this->selectedTilesChanged(selectionOrigin, dimensions.x(), dimensions.y());
|
emit this->selectedTilesChanged(selectionOrigin, dimensions.x(), dimensions.y());
|
||||||
this->drawSelection();
|
this->drawSelection();
|
||||||
} else {
|
} else {
|
||||||
|
int x, y;
|
||||||
|
this->getBoundedCoords(event->pos(), &x, &y);
|
||||||
|
if (prevChangedTile.x() != x || prevChangedTile.y() != y) {
|
||||||
|
this->prevChangedTile.setX(x);
|
||||||
|
this->prevChangedTile.setY(y);
|
||||||
emit this->tileChanged(x, y);
|
emit this->tileChanged(x, y);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetatileLayersItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
|
void MetatileLayersItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
|
@ -77,3 +85,17 @@ void MetatileLayersItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
|
|
||||||
this->draw();
|
this->draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MetatileLayersItem::clearLastModifiedCoords() {
|
||||||
|
this->prevChangedTile.setX(-1);
|
||||||
|
this->prevChangedTile.setY(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MetatileLayersItem::getBoundedCoords(QPointF pos, int *x, int *y) {
|
||||||
|
*x = static_cast<int>(pos.x()) / 16;
|
||||||
|
*y = static_cast<int>(pos.y()) / 16;
|
||||||
|
if (*x < 0) *x = 0;
|
||||||
|
if (*y < 0) *y = 0;
|
||||||
|
if (*x > 3) *x = 3;
|
||||||
|
if (*y > 1) *y = 1;
|
||||||
|
}
|
||||||
|
|
|
@ -49,6 +49,9 @@ void TilesetEditor::init(Project *project, QString primaryTilesetLabel, QString
|
||||||
this->initTileSelector();
|
this->initTileSelector();
|
||||||
this->initSelectedTileItem();
|
this->initSelectedTileItem();
|
||||||
this->metatileSelector->select(0);
|
this->metatileSelector->select(0);
|
||||||
|
|
||||||
|
MetatileHistoryItem *commit = new MetatileHistoryItem(0, nullptr, this->metatile->copy());
|
||||||
|
metatileHistory.push(commit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilesetEditor::setTilesets(QString primaryTilesetLabel, QString secondaryTilesetLabel) {
|
void TilesetEditor::setTilesets(QString primaryTilesetLabel, QString secondaryTilesetLabel) {
|
||||||
|
@ -191,6 +194,7 @@ void TilesetEditor::onSelectedTilesChanged() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilesetEditor::onMetatileLayerTileChanged(int x, int y) {
|
void TilesetEditor::onMetatileLayerTileChanged(int x, int y) {
|
||||||
|
Metatile *prevMetatile = this->metatile->copy();
|
||||||
int maxTileIndex = x < 2 ? 3 : 7;
|
int maxTileIndex = x < 2 ? 3 : 7;
|
||||||
QPoint dimensions = this->tileSelector->getSelectionDimensions();
|
QPoint dimensions = this->tileSelector->getSelectionDimensions();
|
||||||
QList<Tile> tiles = this->tileSelector->getSelectedTiles();
|
QList<Tile> tiles = this->tileSelector->getSelectedTiles();
|
||||||
|
@ -213,6 +217,9 @@ void TilesetEditor::onMetatileLayerTileChanged(int x, int y) {
|
||||||
this->metatileSelector->draw();
|
this->metatileSelector->draw();
|
||||||
this->metatileLayersItem->draw();
|
this->metatileLayersItem->draw();
|
||||||
this->hasUnsavedChanges = true;
|
this->hasUnsavedChanges = true;
|
||||||
|
|
||||||
|
MetatileHistoryItem *commit = new MetatileHistoryItem(metatileSelector->getSelectedMetatile(), prevMetatile, this->metatile->copy());
|
||||||
|
metatileHistory.push(commit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilesetEditor::onMetatileLayerSelectionChanged(QPoint selectionOrigin, int width, int height) {
|
void TilesetEditor::onMetatileLayerSelectionChanged(QPoint selectionOrigin, int width, int height) {
|
||||||
|
@ -228,6 +235,7 @@ void TilesetEditor::onMetatileLayerSelectionChanged(QPoint selectionOrigin, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->tileSelector->setExternalSelection(width, height, tiles);
|
this->tileSelector->setExternalSelection(width, height, tiles);
|
||||||
|
this->metatileLayersItem->clearLastModifiedCoords();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilesetEditor::on_spinBox_paletteSelector_valueChanged(int paletteId)
|
void TilesetEditor::on_spinBox_paletteSelector_valueChanged(int paletteId)
|
||||||
|
@ -241,6 +249,7 @@ void TilesetEditor::on_spinBox_paletteSelector_valueChanged(int paletteId)
|
||||||
if (this->paletteEditor) {
|
if (this->paletteEditor) {
|
||||||
this->paletteEditor->setPaletteId(paletteId);
|
this->paletteEditor->setPaletteId(paletteId);
|
||||||
}
|
}
|
||||||
|
this->metatileLayersItem->clearLastModifiedCoords();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilesetEditor::on_checkBox_xFlip_stateChanged(int checked)
|
void TilesetEditor::on_checkBox_xFlip_stateChanged(int checked)
|
||||||
|
@ -248,6 +257,7 @@ void TilesetEditor::on_checkBox_xFlip_stateChanged(int checked)
|
||||||
this->tileXFlip = checked;
|
this->tileXFlip = checked;
|
||||||
this->tileSelector->setTileFlips(this->tileXFlip, this->tileYFlip);
|
this->tileSelector->setTileFlips(this->tileXFlip, this->tileYFlip);
|
||||||
this->drawSelectedTiles();
|
this->drawSelectedTiles();
|
||||||
|
this->metatileLayersItem->clearLastModifiedCoords();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilesetEditor::on_checkBox_yFlip_stateChanged(int checked)
|
void TilesetEditor::on_checkBox_yFlip_stateChanged(int checked)
|
||||||
|
@ -255,19 +265,26 @@ void TilesetEditor::on_checkBox_yFlip_stateChanged(int checked)
|
||||||
this->tileYFlip = checked;
|
this->tileYFlip = checked;
|
||||||
this->tileSelector->setTileFlips(this->tileXFlip, this->tileYFlip);
|
this->tileSelector->setTileFlips(this->tileXFlip, this->tileYFlip);
|
||||||
this->drawSelectedTiles();
|
this->drawSelectedTiles();
|
||||||
|
this->metatileLayersItem->clearLastModifiedCoords();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilesetEditor::on_comboBox_metatileBehaviors_currentIndexChanged(const QString &metatileBehavior)
|
void TilesetEditor::on_comboBox_metatileBehaviors_activated(const QString &metatileBehavior)
|
||||||
{
|
{
|
||||||
if (this->metatile) {
|
if (this->metatile) {
|
||||||
|
Metatile *prevMetatile = this->metatile->copy();
|
||||||
this->metatile->behavior = static_cast<uint8_t>(project->metatileBehaviorMap[metatileBehavior]);
|
this->metatile->behavior = static_cast<uint8_t>(project->metatileBehaviorMap[metatileBehavior]);
|
||||||
|
MetatileHistoryItem *commit = new MetatileHistoryItem(metatileSelector->getSelectedMetatile(), prevMetatile, this->metatile->copy());
|
||||||
|
metatileHistory.push(commit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilesetEditor::on_comboBox_layerType_currentIndexChanged(int layerType)
|
void TilesetEditor::on_comboBox_layerType_activated(int layerType)
|
||||||
{
|
{
|
||||||
if (this->metatile) {
|
if (this->metatile) {
|
||||||
|
Metatile *prevMetatile = this->metatile->copy();
|
||||||
this->metatile->layerType = static_cast<uint8_t>(layerType);
|
this->metatile->layerType = static_cast<uint8_t>(layerType);
|
||||||
|
MetatileHistoryItem *commit = new MetatileHistoryItem(metatileSelector->getSelectedMetatile(), prevMetatile, this->metatile->copy());
|
||||||
|
metatileHistory.push(commit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,3 +492,40 @@ void TilesetEditor::onPaletteEditorChangedPaletteColor() {
|
||||||
void TilesetEditor::onPaletteEditorChangedPalette(int paletteId) {
|
void TilesetEditor::onPaletteEditorChangedPalette(int paletteId) {
|
||||||
this->on_spinBox_paletteSelector_valueChanged(paletteId);
|
this->on_spinBox_paletteSelector_valueChanged(paletteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TilesetEditor::on_actionUndo_triggered()
|
||||||
|
{
|
||||||
|
MetatileHistoryItem *commit = this->metatileHistory.current();
|
||||||
|
if (!commit) return;
|
||||||
|
Metatile *prev = commit->prevMetatile;
|
||||||
|
if (!prev) return;
|
||||||
|
this->metatileHistory.back();
|
||||||
|
|
||||||
|
Metatile *temp = Tileset::getMetatile(commit->metatileId, this->primaryTileset, this->secondaryTileset);
|
||||||
|
if (temp) {
|
||||||
|
this->metatile = temp;
|
||||||
|
this->metatile->copyInPlace(prev);
|
||||||
|
this->metatileSelector->select(commit->metatileId);
|
||||||
|
this->metatileSelector->draw();
|
||||||
|
this->metatileLayersItem->draw();
|
||||||
|
this->metatileLayersItem->clearLastModifiedCoords();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TilesetEditor::on_actionRedo_triggered()
|
||||||
|
{
|
||||||
|
MetatileHistoryItem *commit = this->metatileHistory.next();
|
||||||
|
if (!commit) return;
|
||||||
|
Metatile *next = commit->newMetatile;
|
||||||
|
if (!next) return;
|
||||||
|
|
||||||
|
Metatile *temp = Tileset::getMetatile(commit->metatileId, this->primaryTileset, this->secondaryTileset);
|
||||||
|
if (temp) {
|
||||||
|
this->metatile = Tileset::getMetatile(commit->metatileId, this->primaryTileset, this->secondaryTileset);
|
||||||
|
this->metatile->copyInPlace(next);
|
||||||
|
this->metatileSelector->select(commit->metatileId);
|
||||||
|
this->metatileSelector->draw();
|
||||||
|
this->metatileLayersItem->draw();
|
||||||
|
this->metatileLayersItem->clearLastModifiedCoords();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue