begin refactoring undo history

This commit is contained in:
garakmon 2020-07-29 15:51:04 -04:00 committed by garak
parent 90aba5e433
commit fb1eec1755
16 changed files with 558 additions and 174 deletions

View file

@ -2711,8 +2711,6 @@
<property name="title">
<string>Edit</string>
</property>
<addaction name="actionUndo"/>
<addaction name="actionRedo"/>
</widget>
<widget class="QMenu" name="menuView">
<property name="title">
@ -2832,25 +2830,6 @@
<string>Ctrl+N</string>
</property>
</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="font">
<font/>
</property>
<property name="shortcut">
<string>Ctrl+Y</string>
</property>
</action>
<action name="action_Export_Map_Image">
<property name="text">
<string>Export Map Image...</string>

168
include/core/editcommands.h Normal file
View file

@ -0,0 +1,168 @@
#ifndef EDITCOMMANDS_H
#define EDITCOMMANDS_H
#include <QUndoCommand>
class MapPixmapItem;
class Map;
class Blockdata;
enum CommandId {
ID_PaintMetatile, // - done
ID_BucketFillMetatile, // - done
ID_MagicFillMetatile, // - done
ID_ShiftMetatiles, // - done
ID_ResizeMap, // - done
ID_PaintBorder, // - done
ID_EventMove, // -
ID_EventCreate, // -
ID_EventDelete, // -
ID_EventSetData, // -
// Tileset editor history commands
// Region map editor history commands
};
/// TODO
class PaintMetatile : public QUndoCommand {
public:
PaintMetatile(Map *map,
Blockdata *oldMetatiles, Blockdata *newMetatiles,
unsigned eventId, QUndoCommand *parent = nullptr);
~PaintMetatile();
void undo() override;
void redo() override;
bool mergeWith(const QUndoCommand *command) override;
int id() const override { return CommandId::ID_PaintMetatile; }
private:
Map *map;
Blockdata *newMetatiles;
Blockdata *oldMetatiles;
unsigned eventId;
};
///
class PaintBorder : public QUndoCommand {
public:
PaintBorder(Map *map,
Blockdata *oldBorder, Blockdata *newBorder,
unsigned eventId, QUndoCommand *parent = nullptr);
~PaintBorder();
void undo() override;
void redo() override;
bool mergeWith(const QUndoCommand *command) override { return false; };
int id() const override { return CommandId::ID_PaintBorder; }
private:
Map *map;
Blockdata *newBorder;
Blockdata *oldBorder;
unsigned eventId;
};
///
class BucketFillMetatile : public PaintMetatile {
public:
BucketFillMetatile(Map *map,
Blockdata *oldMetatiles, Blockdata *newMetatiles,
unsigned eventId, QUndoCommand *parent = nullptr);
~BucketFillMetatile();
bool mergeWith(const QUndoCommand *command) override { return false; }
int id() const override { return CommandId::ID_BucketFillMetatile; }
};
///
class MagicFillMetatile : public PaintMetatile {
public:
MagicFillMetatile(Map *map,
Blockdata *oldMetatiles, Blockdata *newMetatiles,
unsigned eventId, QUndoCommand *parent = nullptr);
~MagicFillMetatile();
bool mergeWith(const QUndoCommand *command) override { return false; }
int id() const override { return CommandId::ID_BucketFillMetatile; }
};
///
class ShiftMetatiles : public QUndoCommand {
public:
ShiftMetatiles(Map *map,
Blockdata *oldMetatiles, Blockdata *newMetatiles,
unsigned eventId, QUndoCommand *parent = nullptr);
~ShiftMetatiles();
void undo() override;
void redo() override;
bool mergeWith(const QUndoCommand *command) override;
int id() const override { return CommandId::ID_ShiftMetatiles; }
private:
Map *map;
Blockdata *newMetatiles;
Blockdata *oldMetatiles;
unsigned eventId;
bool mergeable = false;
};
///
class ResizeMap : public QUndoCommand {
public:
ResizeMap(Map *map, QSize oldMapDimensions, QSize newMapDimensions,
Blockdata *oldMetatiles, Blockdata *newMetatiles,
QSize oldBorderDimensions, QSize newBorderDimensions,
Blockdata *oldBorder, Blockdata *newBorder,
QUndoCommand *parent = nullptr);
~ResizeMap();
void undo() override;
void redo() override;
bool mergeWith(const QUndoCommand *command) override { return false; }
int id() const override { return CommandId::ID_ResizeMap; }
private:
Map *map;
int oldMapWidth;
int oldMapHeight;
int newMapWidth;
int newMapHeight;
int oldBorderWidth;
int oldBorderHeight;
int newBorderWidth;
int newBorderHeight;
Blockdata *newMetatiles;
Blockdata *oldMetatiles;
Blockdata *newBorder;
Blockdata *oldBorder;
};
#endif // EDITCOMMANDS_H

View file

@ -9,6 +9,7 @@
#include "tileset.h"
#include "event.h"
#include <QUndoStack>
#include <QPixmap>
#include <QObject>
#include <QGraphicsPixmapItem>
@ -21,6 +22,9 @@
// porymap will reflect changes to it, but the value is hard-coded in the projects at the moment
#define BORDER_DISTANCE 7
class MapPixmapItem;
class BorderMetatilesPixmapItem;
class Map : public QObject
{
Q_OBJECT
@ -80,9 +84,6 @@ public:
void floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
void _floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
void magicFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
void undo();
void redo();
void commit();
QList<Event*> getAllEvents();
void removeEvent(Event*);
void addEvent(Event*);
@ -93,6 +94,16 @@ public:
void cacheBorder();
bool hasUnsavedChanges();
MapPixmapItem *mapItem = nullptr;
void setMapItem(MapPixmapItem *item) { mapItem = item; }
BorderMetatilesPixmapItem *borderItem = nullptr;
void setBorderItem(BorderMetatilesPixmapItem *item) { borderItem = item; }
void commit(); // TODO: delete this
QUndoStack editHistory;
private:
void setNewDimensionsBlockdata(int newWidth, int newHeight);
void setNewBorderDimensionsBlockdata(int newWidth, int newHeight);

View file

@ -23,7 +23,7 @@ public:
QString tileset_secondary_label;
Tileset *tileset_primary = nullptr;
Tileset *tileset_secondary = nullptr;
Blockdata* blockdata = nullptr;
Blockdata *blockdata = nullptr;
QImage border_image;
QPixmap border_pixmap;
Blockdata *border = nullptr;

View file

@ -16,7 +16,7 @@ struct WildMonInfo {
};
struct WildPokemonHeader {
QMap<QString, WildMonInfo> wildMons;
QHash<QString, WildMonInfo> wildMons;
};
struct EncounterField {

View file

@ -8,6 +8,7 @@
#include <QComboBox>
#include <QCheckBox>
#include <QCursor>
#include <QUndoGroup>
#include "mapconnection.h"
#include "metatileselector.h"
@ -45,8 +46,6 @@ public:
Settings *settings;
void saveProject();
void save();
void undo();
void redo();
void closeProject();
bool setMap(QString map_name);
void saveUiFields();
@ -144,6 +143,8 @@ public:
int getBorderDrawDistance(int dimension);
QUndoGroup editGroup; // Manages the undo history for each map
private:
void setConnectionItemsVisible(bool);
void setBorderItemsVisible(bool, qreal = 1);

View file

@ -121,8 +121,6 @@ private slots:
void on_action_Save_Project_triggered();
void openWarpMap(QString map_name, QString warp_num);
void undo();
void redo();
void duplicate();
void openInTextEditor();
@ -157,9 +155,6 @@ private slots:
void on_mainTabBar_tabBarClicked(int index);
void on_actionUndo_triggered();
void on_actionRedo_triggered();
void on_actionZoom_In_triggered();
void on_actionZoom_Out_triggered();
void on_actionBetter_Cursors_triggered();
@ -252,6 +247,9 @@ private:
QIcon* mapEditedIcon;
QIcon* mapOpenedIcon;
QAction *undoAction;
QAction *redoAction;
QWidget *eventTabObjectWidget;
QWidget *eventTabWarpWidget;
QWidget *eventTabTriggerWidget;

View file

@ -10,11 +10,12 @@ class BorderMetatilesPixmapItem : public QObject, public QGraphicsPixmapItem {
public:
BorderMetatilesPixmapItem(Map *map_, MetatileSelector *metatileSelector) {
this->map = map_;
this->map->setBorderItem(this);
this->metatileSelector = metatileSelector;
setAcceptHoverEvents(true);
}
MetatileSelector *metatileSelector;
Map* map;
Map *map;
void draw();
signals:
void borderMetatilesChanged();

View file

@ -20,6 +20,7 @@ public:
};
MapPixmapItem(Map *map_, MetatileSelector *metatileSelector, Settings *settings) {
this->map = map_;
this->map->setMapItem(this);
this->metatileSelector = metatileSelector;
this->settings = settings;
this->paintingMode = PaintMode::Metatiles;
@ -68,6 +69,8 @@ private:
void paintSmartPath(int x, int y, bool fromScriptCall = false);
static QList<int> smartPathTable;
unsigned eventId_ = 0;
signals:
void startPaint(QGraphicsSceneMouseEvent *, MapPixmapItem *);
void endPaint(QGraphicsSceneMouseEvent *, MapPixmapItem *);

View file

@ -30,6 +30,7 @@ SOURCES += src/core/block.cpp \
src/core/tileset.cpp \
src/core/regionmap.cpp \
src/core/wildmoninfo.cpp \
src/core/editcommands.cpp \
src/lib/orderedjson.cpp \
src/mainwindow_scriptapi.cpp \
src/ui/aboutporymap.cpp \
@ -95,6 +96,7 @@ HEADERS += include/core/block.h \
include/core/tileset.h \
include/core/regionmap.h \
include/core/wildmoninfo.h \
include/core/editcommands.h \
include/lib/orderedmap.h \
include/lib/orderedjson.h \
include/ui/aboutporymap.h \

268
src/core/editcommands.cpp Normal file
View file

@ -0,0 +1,268 @@
#include "editcommands.h"
#include "mappixmapitem.h"
#include "bordermetatilespixmapitem.h"
#include <QDebug>
PaintMetatile::PaintMetatile(Map *map,
Blockdata *oldMetatiles, Blockdata *newMetatiles,
unsigned eventId, QUndoCommand *parent) : QUndoCommand(parent) {
setText("Paint Metatiles");
this->map = map;
this->oldMetatiles = oldMetatiles;
this->newMetatiles = newMetatiles;
this->eventId = eventId;
}
PaintMetatile::~PaintMetatile() {
if (newMetatiles) delete newMetatiles;
if (oldMetatiles) delete oldMetatiles;
}
void PaintMetatile::redo() {
QUndoCommand::redo();
if (!map) return;
if (map->layout->blockdata) {
map->layout->blockdata->copyFrom(newMetatiles);
}
map->mapItem->draw();
}
void PaintMetatile::undo() {
if (!map) return;
if (map->layout->blockdata) {
map->layout->blockdata->copyFrom(oldMetatiles);
}
map->mapItem->draw();
QUndoCommand::undo();
}
bool PaintMetatile::mergeWith(const QUndoCommand *command) {
// does an up merge
const PaintMetatile *other = static_cast<const PaintMetatile *>(command);
if (this->map != other->map)
return false;
if (eventId != other->eventId)
return false;
this->newMetatiles->copyFrom(other->newMetatiles);
return true;
}
/******************************************************************************
************************************************************************
******************************************************************************/
PaintBorder::PaintBorder(Map *map,
Blockdata *oldBorder, Blockdata *newBorder,
unsigned eventId, QUndoCommand *parent) : QUndoCommand(parent) {
setText("Paint Border");
this->map = map;
this->oldBorder = oldBorder;
this->newBorder = newBorder;
this->eventId = eventId;
}
PaintBorder::~PaintBorder() {
if (newBorder) delete newBorder;
if (oldBorder) delete oldBorder;
}
void PaintBorder::redo() {
QUndoCommand::redo();
if (!map) return;
if (map->layout->border) {
map->layout->border->copyFrom(newBorder);
}
map->borderItem->draw();
}
void PaintBorder::undo() {
if (!map) return;
if (map->layout->border) {
map->layout->border->copyFrom(oldBorder);
}
map->borderItem->draw();
QUndoCommand::undo();
}
/******************************************************************************
************************************************************************
******************************************************************************/
BucketFillMetatile::BucketFillMetatile(Map *map,
Blockdata *oldMetatiles, Blockdata *newMetatiles,
unsigned eventId, QUndoCommand *parent)
: PaintMetatile(map, oldMetatiles, newMetatiles, eventId, parent) {
setText("Bucket Fill Metatiles");
}
BucketFillMetatile::~BucketFillMetatile() {
PaintMetatile::~PaintMetatile();
}
/******************************************************************************
************************************************************************
******************************************************************************/
MagicFillMetatile::MagicFillMetatile(Map *map,
Blockdata *oldMetatiles, Blockdata *newMetatiles,
unsigned eventId, QUndoCommand *parent)
: PaintMetatile(map, oldMetatiles, newMetatiles, eventId, parent) {
setText("Magic Fill Metatiles");
}
MagicFillMetatile::~MagicFillMetatile() {
PaintMetatile::~PaintMetatile();
}
/******************************************************************************
************************************************************************
******************************************************************************/
ShiftMetatiles::ShiftMetatiles(Map *map,
Blockdata *oldMetatiles, Blockdata *newMetatiles,
unsigned eventId, QUndoCommand *parent) : QUndoCommand(parent) {
setText("Shift Metatiles");
this->map = map;
this->oldMetatiles = oldMetatiles;
this->newMetatiles = newMetatiles;
this->eventId = eventId;
}
ShiftMetatiles::~ShiftMetatiles() {
if (newMetatiles) delete newMetatiles;
if (oldMetatiles) delete oldMetatiles;
}
void ShiftMetatiles::redo() {
QUndoCommand::redo();
if (!map) return;
if (map->layout->blockdata) {
map->layout->blockdata->copyFrom(newMetatiles);
}
map->mapItem->draw(true);
}
void ShiftMetatiles::undo() {
if (!map) return;
if (map->layout->blockdata) {
map->layout->blockdata->copyFrom(oldMetatiles);
}
map->mapItem->draw(true);
QUndoCommand::undo();
}
bool ShiftMetatiles::mergeWith(const QUndoCommand *command) {
const ShiftMetatiles *other = static_cast<const ShiftMetatiles *>(command);
if (this->map != other->map)
return false;
if (eventId != other->eventId)
return false;
this->newMetatiles->copyFrom(other->newMetatiles);
return true;
}
/******************************************************************************
************************************************************************
******************************************************************************/
ResizeMap::ResizeMap(Map *map, QSize oldMapDimensions, QSize newMapDimensions,
Blockdata *oldMetatiles, Blockdata *newMetatiles,
QSize oldBorderDimensions, QSize newBorderDimensions,
Blockdata *oldBorder, Blockdata *newBorder,
QUndoCommand *parent) : QUndoCommand(parent) {
setText("Resize Map");
this->map = map;
this->oldMapWidth = oldMapDimensions.width();
this->oldMapHeight = oldMapDimensions.height();
this->newMapWidth = newMapDimensions.width();
this->newMapHeight = newMapDimensions.height();
this->oldMetatiles = oldMetatiles;
this->newMetatiles = newMetatiles;
this->oldBorderWidth = oldBorderDimensions.width();
this->oldBorderHeight = oldBorderDimensions.height();
this->newBorderWidth = newBorderDimensions.width();
this->newBorderHeight = newBorderDimensions.height();
this->oldBorder = oldBorder;
this->newBorder = newBorder;
}
ResizeMap::~ResizeMap() {
if (newMetatiles) delete newMetatiles;
if (oldMetatiles) delete oldMetatiles;
}
void ResizeMap::redo() {
QUndoCommand::redo();
if (!map) return;
if (map->layout->blockdata) {
map->layout->blockdata->copyFrom(newMetatiles);
map->setDimensions(newMapWidth, newMapHeight, false);
}
if (map->layout->border) {
map->layout->border->copyFrom(newBorder);
map->setBorderDimensions(newBorderWidth, newBorderHeight, false);
}
}
void ResizeMap::undo() {
if (!map) return;
if (map->layout->blockdata) {
map->layout->blockdata->copyFrom(oldMetatiles);
map->setDimensions(oldMapWidth, oldMapHeight, false);
}
if (map->layout->border) {
map->layout->border->copyFrom(oldBorder);
map->setBorderDimensions(oldBorderWidth, oldBorderHeight, false);
}
QUndoCommand::undo();
}

View file

@ -4,6 +4,8 @@
#include "imageproviders.h"
#include "scripting.h"
#include "editcommands.h"
#include <QTime>
#include <QPainter>
#include <QImage>
@ -343,6 +345,7 @@ void Map::setDimensions(int newWidth, int newHeight, bool setNewBlockdata) {
layout->height = QString::number(newHeight);
emit mapChanged(this);
emit mapNeedsRedrawing();
}
void Map::setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata) {
@ -354,6 +357,7 @@ void Map::setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata)
layout->border_height = QString::number(newHeight);
emit mapChanged(this);
emit mapNeedsRedrawing();
}
Block* Map::getBlock(int x, int y) {
@ -413,93 +417,8 @@ void Map::_floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_
}
}
void Map::undo() {
bool redraw = false, changed = false;
HistoryItem *commit = metatileHistory.back();
if (!commit)
return;
if (layout->blockdata) {
layout->blockdata->copyFrom(commit->metatiles);
if (commit->layoutWidth != this->getWidth() || commit->layoutHeight != this->getHeight()) {
this->setDimensions(commit->layoutWidth, commit->layoutHeight, false);
redraw = true;
}
changed = true;
}
if (layout->border) {
layout->border->copyFrom(commit->border);
if (commit->borderWidth != this->getBorderWidth() || commit->borderHeight != this->getBorderHeight()) {
this->setBorderDimensions(commit->borderWidth, commit->borderHeight, false);
redraw = true;
}
changed = true;
}
if (redraw) {
emit mapNeedsRedrawing();
}
if (changed) {
emit mapChanged(this);
}
}
void Map::redo() {
bool redraw = false, changed = false;
HistoryItem *commit = metatileHistory.next();
if (!commit)
return;
if (layout->blockdata) {
layout->blockdata->copyFrom(commit->metatiles);
if (commit->layoutWidth != this->getWidth() || commit->layoutHeight != this->getHeight()) {
this->setDimensions(commit->layoutWidth, commit->layoutHeight, false);
redraw = true;
}
changed = true;
}
if (layout->border) {
layout->border->copyFrom(commit->border);
if (commit->borderWidth != this->getBorderWidth() || commit->borderHeight != this->getBorderHeight()) {
this->setBorderDimensions(commit->borderWidth, commit->borderHeight, false);
redraw = true;
}
changed = true;
}
if (redraw) {
emit mapNeedsRedrawing();
}
if (changed) {
emit mapChanged(this);
}
}
void Map::commit() {
if (!layout) {
return;
}
int layoutWidth = this->getWidth();
int layoutHeight = this->getHeight();
int borderWidth = this->getBorderWidth();
int borderHeight = this->getBorderHeight();
if (layout->blockdata) {
HistoryItem *item = metatileHistory.current();
bool atCurrentHistory = item
&& layout->blockdata->equals(item->metatiles)
&& layout->border->equals(item->border)
&& layoutWidth == item->layoutWidth
&& layoutHeight == item->layoutHeight
&& borderWidth == item->borderWidth
&& borderHeight == item->borderHeight;
if (!atCurrentHistory) {
HistoryItem *commit = new HistoryItem(layout->blockdata->copy(), layout->border->copy(), layoutWidth, layoutHeight, borderWidth, borderHeight);
metatileHistory.push(commit);
emit mapChanged(this);
}
}
return;
}
void Map::floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation) {

View file

@ -53,26 +53,6 @@ void Editor::saveUiFields() {
saveEncounterTabData();
}
void Editor::undo() {
if (current_view && map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles) {
map->undo();
map_item->draw();
collision_item->draw();
selected_border_metatiles_item->draw();
onBorderMetatilesChanged();
}
}
void Editor::redo() {
if (current_view && map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles) {
map->redo();
map_item->draw();
collision_item->draw();
selected_border_metatiles_item->draw();
onBorderMetatilesChanged();
}
}
void Editor::closeProject() {
if (this->project) {
delete this->project;
@ -981,6 +961,9 @@ bool Editor::setMap(QString map_name) {
}
map = loadedMap;
editGroup.addStack(&map->editHistory);
editGroup.setActiveStack(&map->editHistory);
selected_events->clear();
if (!displayMap()) {
return false;

View file

@ -11,6 +11,7 @@
#include "customattributestable.h"
#include "scripting.h"
#include "adjustingstackedwidget.h"
#include "editcommands.h"
#include <QFileDialog>
#include <QDirIterator>
@ -146,6 +147,21 @@ void MainWindow::initEditor() {
connect(this->editor, &Editor::wheelZoom, this, &MainWindow::onWheelZoom);
this->loadUserSettings();
undoAction = editor->editGroup.createUndoAction(this, tr("&Undo"));
undoAction->setShortcut(QKeySequence("Ctrl+Z"));
redoAction = editor->editGroup.createRedoAction(this, tr("&Redo"));
redoAction->setShortcut(QKeySequence("Ctrl+Y"));
ui->menuEdit->addAction(undoAction);
ui->menuEdit->addAction(redoAction);
// TODO: show history UndoView here
QUndoView *undoView = new QUndoView(&editor->editGroup);
undoView->setWindowTitle(tr("Edit History"));
undoView->show();
undoView->setAttribute(Qt::WA_QuitOnClose, false);
}
void MainWindow::initMiscHeapObjects() {
@ -1255,14 +1271,6 @@ void MainWindow::on_action_Save_Project_triggered()
updateMapList();
}
void MainWindow::undo() {
editor->undo();
}
void MainWindow::redo() {
editor->redo();
}
void MainWindow::duplicate() {
editor->duplicateSelectedEvents();
}
@ -1322,16 +1330,6 @@ void MainWindow::on_mainTabBar_tabBarClicked(int index)
}
}
void MainWindow::on_actionUndo_triggered()
{
undo();
}
void MainWindow::on_actionRedo_triggered()
{
redo();
}
void MainWindow::on_actionZoom_In_triggered() {
scaleMapView(1);
}
@ -2498,10 +2496,23 @@ void MainWindow::on_pushButton_ChangeDimensions_clicked()
form.addRow(errorLabel);
if (dialog.exec() == QDialog::Accepted) {
editor->map->setDimensions(widthSpinBox->value(), heightSpinBox->value());
editor->map->setBorderDimensions(bwidthSpinBox->value(), bheightSpinBox->value());
editor->map->commit();
onMapNeedsRedrawing();
Map *map = editor->map;
Blockdata *oldMetatiles = map->layout->blockdata->copy();
Blockdata *oldBorder = map->layout->border->copy();
QSize oldMapDimensions(map->getWidth(), map->getHeight());
QSize oldBorderDimensions(map->getBorderWidth(), map->getBorderHeight());
QSize newMapDimensions(widthSpinBox->value(), heightSpinBox->value());
QSize newBorderDimensions(bwidthSpinBox->value(), bheightSpinBox->value());
if (oldMapDimensions != newMapDimensions || oldBorderDimensions != newBorderDimensions) {
editor->map->setDimensions(newMapDimensions.width(), newMapDimensions.height());
editor->map->setBorderDimensions(newBorderDimensions.width(), newBorderDimensions.height());
editor->map->editHistory.push(new ResizeMap(map,
oldMapDimensions, newMapDimensions,
oldMetatiles, map->layout->blockdata->copy(),
oldBorderDimensions, newBorderDimensions,
oldBorder, map->layout->border->copy()
));
}
}
}

View file

@ -1,5 +1,6 @@
#include "bordermetatilespixmapitem.h"
#include "imageproviders.h"
#include "editcommands.h"
#include <QPainter>
void BorderMetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
@ -11,6 +12,8 @@ void BorderMetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
int width = map->getBorderWidth();
int height = map->getBorderHeight();
Blockdata *oldBorder = map->layout->border->copy();
for (int i = 0; i < selectionDimensions.x() && (i + x) < width; i++) {
for (int j = 0; j < selectionDimensions.y() && (j + y) < height; j++) {
int blockIndex = (j + y) * width + (i + x);
@ -19,11 +22,15 @@ void BorderMetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
}
}
draw();
Blockdata *newBorder = map->layout->border->copy();
map->editHistory.push(new PaintBorder(map, oldBorder, newBorder, 0));
emit borderMetatilesChanged();
}
void BorderMetatilesPixmapItem::draw() {
map->setBorderItem(this);
int width = map->getBorderWidth();
int height = map->getBorderHeight();
QImage image(16 * width, 16 * height, QImage::Format_RGBA8888);
@ -49,4 +56,6 @@ void BorderMetatilesPixmapItem::draw() {
painter.end();
map->commit();
this->setPixmap(QPixmap::fromImage(image));
emit borderMetatilesChanged();
}

View file

@ -1,12 +1,14 @@
#include "mappixmapitem.h"
#include "log.h"
#include "editcommands.h"
#define SWAP(a, b) do { if (a != b) { a ^= b; b ^= a; a ^= b; } } while (0)
void MapPixmapItem::paint(QGraphicsSceneMouseEvent *event) {
if (map) {
if (event->type() == QEvent::GraphicsSceneMouseRelease) {
map->commit();
eventId_++;
} else {
QPointF pos = event->pos();
int x = static_cast<int>(pos.x()) / 16;
@ -21,15 +23,13 @@ void MapPixmapItem::paint(QGraphicsSceneMouseEvent *event) {
paintNormal(x, y);
}
}
draw();
}
}
void MapPixmapItem::shift(QGraphicsSceneMouseEvent *event) {
if (map) {
if (event->type() == QEvent::GraphicsSceneMouseRelease) {
map->commit();
eventId_++;
} else {
QPointF pos = event->pos();
int x = static_cast<int>(pos.x()) / 16;
@ -70,7 +70,9 @@ void MapPixmapItem::shift(int xDelta, int yDelta) {
map->setBlock(destX, destY, srcBlock);
}
delete backupBlockdata;
Blockdata *newMetatiles = map->layout->blockdata->copy();
ShiftMetatiles *paintEvent = new ShiftMetatiles(map, backupBlockdata, newMetatiles, eventId_);
map->editHistory.push(paintEvent);
}
void MapPixmapItem::paintNormal(int x, int y, bool fromScriptCall) {
@ -90,6 +92,9 @@ void MapPixmapItem::paintNormal(int x, int y, bool fromScriptCall) {
x = initialX + (xDiff / selectionDimensions.x()) * selectionDimensions.x();
y = initialY + (yDiff / selectionDimensions.y()) * selectionDimensions.y();
// for edit history
Blockdata *oldMetatiles = map->layout->blockdata->copy();
for (int i = 0; i < selectionDimensions.x() && i + x < map->getWidth(); i++)
for (int j = 0; j < selectionDimensions.y() && j + y < map->getHeight(); j++) {
int actualX = i + x;
@ -105,6 +110,10 @@ void MapPixmapItem::paintNormal(int x, int y, bool fromScriptCall) {
map->setBlock(actualX, actualY, *block, !fromScriptCall);
}
}
Blockdata *newMetatiles = map->layout->blockdata->copy();
PaintMetatile *paintEvent = new PaintMetatile(map, oldMetatiles, newMetatiles, eventId_);
map->editHistory.push(paintEvent);
}
// These are tile offsets from the top-left tile in the 3x3 smart path selection.
@ -150,6 +159,9 @@ void MapPixmapItem::paintSmartPath(int x, int y, bool fromScriptCall) {
setCollisions = true;
}
// for edit history
Blockdata *oldMetatiles = map->layout->blockdata->copy();
// Fill the region with the open tile.
for (int i = 0; i <= 1; i++)
for (int j = 0; j <= 1; j++) {
@ -211,6 +223,10 @@ void MapPixmapItem::paintSmartPath(int x, int y, bool fromScriptCall) {
}
map->setBlock(actualX, actualY, *block, !fromScriptCall);
}
Blockdata *newMetatiles = map->layout->blockdata->copy();
PaintMetatile *paintEvent = new PaintMetatile(map, oldMetatiles, newMetatiles, eventId_);
map->editHistory.push(paintEvent);
}
void MapPixmapItem::updateMetatileSelection(QGraphicsSceneMouseEvent *event) {
@ -263,7 +279,7 @@ void MapPixmapItem::updateMetatileSelection(QGraphicsSceneMouseEvent *event) {
void MapPixmapItem::floodFill(QGraphicsSceneMouseEvent *event) {
if (map) {
if (event->type() == QEvent::GraphicsSceneMouseRelease) {
map->commit();
eventId_++;
} else {
QPointF pos = event->pos();
int x = static_cast<int>(pos.x()) / 16;
@ -280,23 +296,19 @@ void MapPixmapItem::floodFill(QGraphicsSceneMouseEvent *event) {
this->floodFill(x, y);
}
}
draw();
}
}
void MapPixmapItem::magicFill(QGraphicsSceneMouseEvent *event) {
if (map) {
if (event->type() == QEvent::GraphicsSceneMouseRelease) {
map->commit();
eventId_++;
} else {
QPointF pos = event->pos();
int initialX = static_cast<int>(pos.x()) / 16;
int initialY = static_cast<int>(pos.y()) / 16;
this->magicFill(initialX, initialY);
}
draw();
}
}
@ -327,6 +339,8 @@ void MapPixmapItem::magicFill(
return;
}
Blockdata *oldMetatiles = map->layout->blockdata->copy();
bool setCollisions = selectedCollisions && selectedCollisions->length() == selectedMetatiles->length();
uint16_t tile = block->tile;
for (int y = 0; y < map->getHeight(); y++) {
@ -349,6 +363,10 @@ void MapPixmapItem::magicFill(
}
}
}
Blockdata *newMetatiles = map->layout->blockdata->copy();
MagicFillMetatile *paintEvent = new MagicFillMetatile(map, oldMetatiles, newMetatiles, eventId_);
map->editHistory.push(paintEvent);
}
}
@ -379,6 +397,8 @@ void MapPixmapItem::floodFill(
for (int i = 0; i < numMetatiles; i++)
visited[i] = false;
Blockdata *oldMetatiles = map->layout->blockdata->copy();
QList<QPoint> todo;
todo.append(QPoint(initialX, initialY));
while (todo.length()) {
@ -427,6 +447,10 @@ void MapPixmapItem::floodFill(
}
}
Blockdata *newMetatiles = map->layout->blockdata->copy();
BucketFillMetatile *paintEvent = new BucketFillMetatile(map, oldMetatiles, newMetatiles, eventId_);
map->editHistory.push(paintEvent);
delete[] visited;
}
@ -449,6 +473,8 @@ void MapPixmapItem::floodFillSmartPath(int initialX, int initialY, bool fromScri
setCollisions = true;
}
Blockdata *oldMetatiles = map->layout->blockdata->copy();
// Flood fill the region with the open tile.
QList<QPoint> todo;
todo.append(QPoint(initialX, initialY));
@ -548,6 +574,10 @@ void MapPixmapItem::floodFillSmartPath(int initialX, int initialY, bool fromScri
}
}
Blockdata *newMetatiles = map->layout->blockdata->copy();
BucketFillMetatile *paintEvent = new BucketFillMetatile(map, oldMetatiles, newMetatiles, eventId_);
map->editHistory.push(paintEvent);
delete[] visited;
}
@ -595,6 +625,7 @@ void MapPixmapItem::select(QGraphicsSceneMouseEvent *event) {
void MapPixmapItem::draw(bool ignoreCache) {
if (map) {
map->setMapItem(this);
setPixmap(map->render(ignoreCache));
}
}