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 11, 2023
1 parent b3c0f0d commit 2f4d2ea
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 12 deletions.
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
include_directories(source/)
set(PROJECT_SOURCES
source/celview.cpp
source/celview.h
source/celview.ui
source/framecmds.cpp
source/config.cpp
Expand Down
23 changes: 18 additions & 5 deletions source/celview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,9 @@ void CelView::insertFrame(IMAGE_FILE_MODE mode, int index, const QString &imagef
QImageReader reader = QImageReader(imagefilePath);
int numImages = 0;

// FIXME: this loop should have some sort of a progress bar, we support
// status bar, but if user loads a .gif which could contain up to hundreds
// of frames, loading might take quite a bit
while (true) {
QImage image = reader.read();
if (image.isNull()) {
Expand All @@ -224,19 +227,29 @@ void CelView::insertFrame(IMAGE_FILE_MODE mode, int index, const QString &imagef
}
}

void CelView::replaceCurrentFrame(const QString &imagefilePath)
void CelView::replaceCurrentFrame(int frameIdx, const QImage &image)
{
this->gfx->replaceFrame(frameIdx, image);

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

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()
Expand Down
3 changes: 2 additions & 1 deletion source/celview.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,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
17 changes: 17 additions & 0 deletions source/framecmds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,20 @@ void RemoveFrameCommand::redo()
// emit this signal which will call LevelCelView/CelView::removeCurrentFrame
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);
}

20 changes: 20 additions & 0 deletions source/framecmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,23 @@ class RemoveFrameCommand : public QObject, public QUndoCommand {
QImage imgToRevert;
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;
};
14 changes: 12 additions & 2 deletions source/levelcelview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,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 @@ -701,7 +701,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 @@ -55,7 +55,9 @@ class LevelCelView : public QWidget {

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 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 @@ -1085,10 +1085,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 2f4d2ea

Please sign in to comment.