Skip to content

Commit

Permalink
FrameCmds: Make replace frame option to be undoable/redoable
Browse files Browse the repository at this point in the history
This commit makes "replace frame" option to be undoable, it allows to
replace frame and then undo or redo the same action.
  • Loading branch information
tetektoza committed Nov 19, 2023
1 parent 8dae7f2 commit 1cbc1dc
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 17 deletions.
32 changes: 21 additions & 11 deletions source/celview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,29 +229,39 @@ void CelView::sendAddFrameCmd(IMAGE_FILE_MODE mode, int index, const QString &im
undoStack->push(command);
}

void CelView::sendRemoveFrameCmd()
void CelView::replaceCurrentFrame(int frameIdx, const QImage &image)
{
// send a command to undostack, making deleting frame undo/redoable
RemoveFrameCommand *command = new RemoveFrameCommand(this->currentFrameIndex, this->gfx->getFrameImage(this->currentFrameIndex));
QObject::connect(command, &RemoveFrameCommand::removed, this, &CelView::removeCurrentFrame);
QObject::connect(command, &RemoveFrameCommand::inserted, this, &CelView::insertImageFile);
this->gfx->replaceFrame(frameIdx, image);

this->undoStack->push(command);
// update the view
this->initialize(this->gfx);
this->displayFrame();
}

void CelView::replaceCurrentFrame(const QString &imagefilePath)
void CelView::sendReplaceCurrentFrameCmd(const QString &imagefilePath)
{
QImage image = QImage(imagefilePath);

if (image.isNull()) {
return;
}

this->gfx->replaceFrame(this->currentFrameIndex, image);
// send a command to undostack, making replacing frame undo/redoable
ReplaceFrameCommand *command = new ReplaceFrameCommand(this->currentFrameIndex, image, this->gfx->getFrameImage(this->currentFrameIndex));
QObject::connect(command, &ReplaceFrameCommand::replaced, this, &CelView::replaceCurrentFrame);
QObject::connect(command, &ReplaceFrameCommand::undoReplaced, this, &CelView::replaceCurrentFrame);

// update the view
this->initialize(this->gfx);
this->displayFrame();
undoStack->push(command);
}

void CelView::sendRemoveFrameCmd()
{
// send a command to undostack, making deleting frame undo/redoable
RemoveFrameCommand *command = new RemoveFrameCommand(this->currentFrameIndex, this->gfx->getFrameImage(this->currentFrameIndex));
QObject::connect(command, &RemoveFrameCommand::removed, this, &CelView::removeCurrentFrame);
QObject::connect(command, &RemoveFrameCommand::inserted, this, &CelView::insertImageFile);

this->undoStack->push(command);
}

void CelView::removeCurrentFrame(int frameIdx)
Expand Down
3 changes: 2 additions & 1 deletion source/celview.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ class CelView : public QWidget {
int getCurrentFrameIndex();
void framePixelClicked(unsigned x, unsigned y);
void insertImageFiles(IMAGE_FILE_MODE mode, const QStringList &imagefilePaths, bool append);
void replaceCurrentFrame(const QString &imagefilePath);
void sendReplaceCurrentFrameCmd(const QString &imagefilePath);
void replaceCurrentFrame(int frameIdx, const QImage &image);
void removeCurrentFrame(int frameIdx);
void regroupFrames(int numGroups);
void updateGroupIndex();
Expand Down
18 changes: 18 additions & 0 deletions source/framecmds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,24 @@ void RemoveFrameCommand::redo()
emit this->removed(frameIndexToRevert);
}

ReplaceFrameCommand::ReplaceFrameCommand(int currentFrameIndex, const QImage imgToReplace, const QImage imgToRestore, QUndoCommand *parent)
: frameIndexToReplace(currentFrameIndex)
, imgToReplace(imgToReplace)
, imgToRestore(imgToRestore)
{
}

void ReplaceFrameCommand::undo()
{
emit this->undoReplaced(frameIndexToReplace, imgToRestore);
}

void ReplaceFrameCommand::redo()
{
// emit this signal which will call LevelCelView/CelView::replaceCurrentFrame
emit this->replaced(frameIndexToReplace, imgToReplace);
}

AddFrameCommand::AddFrameCommand(IMAGE_FILE_MODE mode, int index, const QString imagefilePath, QUndoCommand *parent)
: startingIndex(index)
, mode(mode)
Expand Down
20 changes: 20 additions & 0 deletions source/framecmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,26 @@ class RemoveFrameCommand : public QObject, public QUndoCommand {
int frameIndexToRevert = 0;
};

class ReplaceFrameCommand : public QObject, public QUndoCommand {
Q_OBJECT

public:
explicit ReplaceFrameCommand(int currentFrameIndex, const QImage imgToReplace, const QImage imgToRestore, QUndoCommand *parent = nullptr);
~ReplaceFrameCommand() = default;

void undo() override;
void redo() override;

signals:
void undoReplaced(int idxToRemove, const QImage imgToRestore);
void replaced(int idxToReplace, const QImage imgToReplace);

private:
QImage imgToReplace;
QImage imgToRestore;
int frameIndexToReplace = 0;
};

class AddFrameCommand : public QObject, public QUndoCommand {
Q_OBJECT

Expand Down
14 changes: 12 additions & 2 deletions source/levelcelview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ void LevelCelView::insertTiles(IMAGE_FILE_MODE mode, const QStringList &imagefil
this->displayFrame();
}

void LevelCelView::replaceCurrentFrame(const QString &imagefilePath)
void LevelCelView::sendReplaceCurrentFrameCmd(const QString &imagefilePath)
{
QImage image = QImage(imagefilePath);

Expand All @@ -728,7 +728,17 @@ void LevelCelView::replaceCurrentFrame(const QString &imagefilePath)
return;
}

D1GfxFrame *frame = this->gfx->replaceFrame(this->currentFrameIndex, image);
// send a command to undostack, making replacing frame undo/redoable
ReplaceFrameCommand *command = new ReplaceFrameCommand(this->currentFrameIndex, image, this->gfx->getFrameImage(this->currentFrameIndex));
QObject::connect(command, &ReplaceFrameCommand::replaced, this, &LevelCelView::replaceCurrentFrame);
QObject::connect(command, &ReplaceFrameCommand::undoReplaced, this, &LevelCelView::replaceCurrentFrame);

undoStack->push(command);
}

void LevelCelView::replaceCurrentFrame(int frameIdx, const QImage &image)
{
D1GfxFrame *frame = this->gfx->replaceFrame(frameIdx, image);

if (frame != nullptr) {
LevelTabFrameWidget::selectFrameType(frame);
Expand Down
4 changes: 3 additions & 1 deletion source/levelcelview.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,16 @@ class LevelCelView : public QWidget {
int getCurrentFrameIndex();
int getCurrentSubtileIndex();
int getCurrentTileIndex();
void replaceCurrentFrame(const QString &imagefilePath);

void framePixelClicked(unsigned x, unsigned y);

void insertImageFiles(IMAGE_FILE_MODE mode, const QStringList &imagefilePaths, bool append);

void sendAddFrameCmd(IMAGE_FILE_MODE mode, int index, const QString &imagefilePath);

void sendReplaceCurrentFrameCmd(const QString &imagefilePath);
void replaceCurrentFrame(int frameIdx, const QImage &image);

void sendRemoveFrameCmd();
void removeCurrentFrame(int idx);

Expand Down
4 changes: 2 additions & 2 deletions source/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1084,10 +1084,10 @@ void MainWindow::on_actionReplace_Frame_triggered()
this->ui->statusBar->repaint();

if (this->celView != nullptr) {
this->celView->replaceCurrentFrame(imgFilePath);
this->celView->sendReplaceCurrentFrameCmd(imgFilePath);
}
if (this->levelCelView != nullptr) {
this->levelCelView->replaceCurrentFrame(imgFilePath);
this->levelCelView->sendReplaceCurrentFrameCmd(imgFilePath);
}
this->updateWindow();

Expand Down

0 comments on commit 1cbc1dc

Please sign in to comment.