Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New undo/redo implementation #953

Closed
wants to merge 116 commits into from
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
aee9c6a
Add new undo/redo implementation
MrStevns Apr 22, 2018
751143c
Merge branch 'master' into undo-redo-rewrite
candyface May 7, 2018
6c35536
Merge branch 'master' into undo-redo-rewrite
candyface Jun 11, 2018
7c3d540
Merge remote-tracking branch 'remotes/upstream/master' into undo-redo…
chchwy Jun 14, 2018
f2867d3
Fix compiler errors
chchwy Jun 14, 2018
1309f08
Merge pull request #6 from chchwy/undo-redo-rewrite
candyface Jun 14, 2018
b78c268
Remove commented code
MrStevns Aug 4, 2018
1b3e537
Merge branch 'master' into undo-redo-rewrite
MrStevns Sep 30, 2018
578f7a5
No isSequence anymore, use keyspacing
MrStevns Sep 30, 2018
f88d51a
Fix compiler errors and add history to ui
MrStevns Sep 30, 2018
4838911
Add Selection undo/redo WIP
MrStevns Oct 11, 2018
34d40b7
Rework bitmap and transform elements
MrStevns Oct 21, 2018
0c1b77e
Carefully merge master into undo-redo-rewrite
MrStevns Nov 3, 2018
57ef759
Merge branch 'master' into undo-redo-rewrite again...
MrStevns Nov 3, 2018
b6c6d82
Apply better naming for saving undo state
MrStevns Nov 3, 2018
3e86718
Refactor selectionElement
MrStevns Nov 3, 2018
2cec951
Add backup to keypress transformations
MrStevns Nov 3, 2018
6dff566
Fix clear selection not working
MrStevns Nov 4, 2018
88d23ba
Import bitmap should have its own QUndoCommand
MrStevns Nov 11, 2018
a8c2bc5
Refactor backupelements
MrStevns Nov 11, 2018
7798516
Fix compiler error
MrStevns Nov 11, 2018
01cb743
Fix compiler warnings
MrStevns Nov 24, 2018
7fd65e2
Refactor header and fix comment typo
MrStevns Nov 24, 2018
1a038ce
tr() takes string literal as parameters, not string variables
chchwy Nov 30, 2018
5b1358c
Merge pull request #7 from chchwy/undo-redo-rewrite
candyface Dec 1, 2018
4ebef23
Merge branch 'master' into undo-redo-rewrite
candyface Dec 9, 2018
ab978ba
Merge branch 'master' into undo-redo-rewrite
candyface Dec 14, 2018
2555a73
Begin unit testing
MrStevns Nov 24, 2018
cc92e35
Fix compiler error.
MrStevns Dec 20, 2018
d306ea7
Merge branch 'master' into undo-redo-rewrite
MrStevns Dec 20, 2018
2b86cfa
Fix bitmap bug when drawing on previous frame
MrStevns Jan 13, 2019
7c4e5fb
Remove redundant code...
MrStevns Jan 13, 2019
9d30e71
Fix various bugs related to previous drawing action
MrStevns Jan 18, 2019
d4ed5a7
Refactor BackupManager::restoreLayerKeys
MrStevns Jan 22, 2019
c4feb62
NewFoo are not needed for DeleteLayerElement, as we delete by id
MrStevns Jan 22, 2019
e856de1
RemoveKeyFrame should always undo/redo from oldFoo
MrStevns Jan 22, 2019
76cdc39
AddKeyFrameElement, Refactor and optimize
MrStevns Jan 22, 2019
be2272d
Fix bug where index is >= to lastLayerIndex..
MrStevns Jan 22, 2019
9fe396f
AddKeyFrameElement related, remove unnecessary emit.
MrStevns Jan 23, 2019
96f3241
Fix camera transformation being incorrect when reapplied.
MrStevns Jan 23, 2019
87c8f44
Merge branch 'master' into undo-redo-rewrite
MrStevns Feb 12, 2019
594baef
Merge branch 'master' into undo-redo-rewrite
MrStevns Apr 20, 2019
a52f8cf
Fix compiler errors that occured in merge conflict
MrStevns Apr 20, 2019
9f5379e
Merge branch 'master' into undo-redo-rewrite
MrStevns Jun 30, 2019
7a8c732
Refactor and make const if possible
MrStevns Jun 30, 2019
3a432aa
Refactor backupelement and make params const if possible
MrStevns Jul 2, 2019
8e6a30a
Reposition class methods to correspond to position in header
MrStevns Jul 2, 2019
59db340
Remove scribblearea from Backupmanager
MrStevns Jul 2, 2019
60ea27d
Refactor canvaspainter out of scribblearea
MrStevns Jul 2, 2019
5b2f945
Add deselect backup when outside selection area
MrStevns Jul 3, 2019
bb456fd
Simplify selectionElement
MrStevns Jul 3, 2019
8058d96
Simplify delete selection backup
MrStevns Jul 3, 2019
f8ef7f4
Remove scribblearea from TransformElement and SelectionElement
MrStevns Jul 3, 2019
eaf4846
Refactor addBitmapElement and addVectorElement
MrStevns Jul 3, 2019
169b026
Remove unused header
MrStevns Jul 3, 2019
6d0c8db
Merge branch 'master' into undo-redo-rewrite
candyface Jul 4, 2019
18f1638
Update frame after importing images
MrStevns Jul 4, 2019
6440350
Merge branch 'master' into undo-redo-rewrite
candyface Aug 5, 2019
a5b57cd
Fix bug: duplicate key undo removes wrong keyframe
MrStevns Aug 8, 2019
744bb5c
Improve undo/redo descriptions
MrStevns Aug 8, 2019
c10d24d
Fix restoring camera key would crash with malloc
MrStevns Aug 9, 2019
11af1c3
Apply motion backup on scrolling
MrStevns Aug 9, 2019
7592f32
Fix undo-redo sound keyframe replacing if overlapped
MrStevns Aug 9, 2019
10db303
Fix vector transformation when moving selection
MrStevns Aug 9, 2019
f313390
Fix MoveLayerBackup: Move essential layer swap code to editor
MrStevns Aug 15, 2019
17df292
MoveFrameBackup related: save state earlier..
MrStevns Aug 15, 2019
8e8d221
Fix drawing on empty frame would create a backup even if previous fra…
MrStevns Aug 15, 2019
04e7fb3
Fix vector selection going out of sync
MrStevns Aug 17, 2019
c4705ce
Fix deselection backup being made when there's no selection...
MrStevns Aug 17, 2019
cf7c1d3
MoveTool: fix backups being made unnecessarily
MrStevns Aug 18, 2019
11945ed
Fix transformed image not being applied correctly when selection is u…
MrStevns Aug 18, 2019
bdf5823
SelectTool: Fix potential selection pixel offset for bitmap
MrStevns Aug 18, 2019
7fabfc0
SelectTool: fix no deselect backup being made when creating a selecti…
MrStevns Aug 18, 2019
e8bc894
TransformElement: backup selection flip
MrStevns Aug 21, 2019
2ca81d4
Editor: Revert scrub to previous keyframe
MrStevns Aug 21, 2019
46fb960
Merge branch 'master' into undo-redo-rewrite
candyface Aug 25, 2019
4cc2bf5
Fix compiler error from bad merge
MrStevns Aug 25, 2019
9773d10
Fix camera motion not working properly unless you stood on the correc…
MrStevns Aug 26, 2019
ff6a9a8
Fix selection scaling not working after flip backup implementation
MrStevns Aug 26, 2019
c4c6555
Backup select all and deselect all actions
MrStevns Aug 26, 2019
28ea288
Avoid creating deselect backup unless something is selected.
MrStevns Aug 26, 2019
4247dc4
Fix camera motion zoom backup only working through scroll on mac
MrStevns Aug 26, 2019
de977df
Implement camera motion backup for view actions
MrStevns Aug 26, 2019
a3780c2
Fix camera motion undo action not moving to frame.
MrStevns Aug 26, 2019
c7af12c
Fix camera size not backed up properly
MrStevns Aug 27, 2019
4eea635
Fix selectionelement not backing up vector curves
MrStevns Aug 27, 2019
b827b0d
Rework: remove keyframe act as clear frame when there's only one frame
MrStevns Aug 27, 2019
6876eba
Fix wrong frame being deleted with duplicate previous key action
MrStevns Aug 27, 2019
89d2501
Fix bucket tool backup on vector layer if there's no change.
MrStevns Aug 27, 2019
7661103
Fix scale issue when performing multiple flip selections
MrStevns Aug 28, 2019
5c34c63
Fix problems related to having only one keyframe available on a layer
MrStevns Aug 28, 2019
223d72f
Vector and BitmapElement: make sure correct layer is selected.
MrStevns Aug 28, 2019
d40472d
Fix two cases that could crash program
MrStevns Aug 28, 2019
2d22ed1
Keyframe add/remove: scrub to correct layer
MrStevns Aug 28, 2019
2ee6307
Fix crash when attempting to backup keyframe that is null.
MrStevns Aug 28, 2019
33355ae
EraserTool: fix erased strokes not being backed up properly
MrStevns Aug 28, 2019
3f916d1
Fix bitmap and vector selection behaviours
MrStevns Aug 29, 2019
94bd80c
Fix selectAll not re-selecting all vector strokes
MrStevns Aug 29, 2019
2902a9a
Fix vector stroke selection would always select all strokes.
MrStevns Aug 29, 2019
cb6c220
Implement ability to undo/redo frame selections and non selected fram…
MrStevns Sep 7, 2019
a2dd983
Fix move frame in actioncommands undo/redo would scrub one behind frame
MrStevns Sep 7, 2019
e6d600d
Timelinecells: allow dragging selected frames when selecting on scrub…
MrStevns Sep 7, 2019
356479c
Fix selecting another layer would trigger deselect backup when empty
MrStevns Sep 7, 2019
9e6e5a2
Erasertool: only save on press otherwise might save wrong state
MrStevns Sep 7, 2019
df79035
EraserTool: don't backup vector unless a point is deleted
MrStevns Sep 7, 2019
6a4163b
Fix smudge making backup when not transformed
MrStevns Sep 9, 2019
adca2b2
Tweak duplicate key behavior backup description
MrStevns Sep 9, 2019
af00d79
Fix crash with transform element because pointer was presumably freed
MrStevns Sep 10, 2019
2dc3c4e
Cut backup: Fix another crash related to transformations
MrStevns Sep 10, 2019
0e6b76c
ImportImageElement: always merge
MrStevns Sep 11, 2019
0059bd9
ImportBitmapElement: optimize undo/redo actions
MrStevns Sep 11, 2019
11b656e
Fix vector transform acting up in certain cases:
MrStevns Sep 14, 2019
bfeed49
Fix frame deselecting when moved but mouse isn't on pos
MrStevns Sep 14, 2019
16b660a
Timelinecells: Fix backup not always triggered when selecting and mov…
MrStevns Sep 15, 2019
61ee83c
Simplify timeline move frame backup, revert back to no select frame e…
MrStevns Sep 29, 2019
9021a5c
Fix canvas not being updated after moving frame
MrStevns Sep 29, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 94 additions & 11 deletions app/src/actioncommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ GNU General Public License for more details.
#include "soundmanager.h"
#include "playbackmanager.h"
#include "preferencemanager.h"
#include "backupmanager.h"
#include "util.h"
#include "app_util.h"

Expand Down Expand Up @@ -80,10 +81,12 @@ Status ActionCommands::importSound()
QString strLayerName = QInputDialog::getText(mParent, tr("Layer Properties", "Dialog title on creating a sound layer"),
tr("Layer name:"), QLineEdit::Normal,
tr("Sound Layer", "Default name on creating a sound layer"), &ok);
mEditor->backups()->prepareBackup();
if (ok && !strLayerName.isEmpty())
{
Layer* newLayer = mEditor->layers()->createSoundLayer(strLayerName);
mEditor->layers()->setCurrentLayer(newLayer);
mEditor->backups()->layerAdded();
}
else
{
Expand Down Expand Up @@ -115,6 +118,7 @@ Status ActionCommands::importSound()
layer->addKeyFrame(currentFrame, key);
}

mEditor->backups()->prepareBackup();
FileDialog fileDialog(mParent);
QString strSoundFile = fileDialog.openFile(FileType::SOUND);

Expand All @@ -124,6 +128,7 @@ Status ActionCommands::importSound()
}

Status st = mEditor->sound()->loadSound(key, strSoundFile);
mEditor->backups()->keyAdded();

if (!st.ok())
{
Expand All @@ -150,7 +155,7 @@ Status ActionCommands::exportMovie(bool isGif)
OnScopeExit(dialog->deleteLater());

dialog->init();

std::vector< std::pair<QString, QSize> > camerasInfo;
auto cameraLayers = mEditor->object()->getLayersByType< LayerCamera >();
for (LayerCamera* i : cameraLayers)
Expand Down Expand Up @@ -180,7 +185,7 @@ Status ActionCommands::exportMovie(bool isGif)

dialog->setDefaultRange(1, length, lengthWithSounds);
dialog->exec();

if (dialog->result() == QDialog::Rejected)
{
return Status::SAFE;
Expand Down Expand Up @@ -263,7 +268,7 @@ Status ActionCommands::exportImageSequence()
{
auto dialog = new ExportImageDialog(mParent, FileType::IMAGE_SEQUENCE);
OnScopeExit(dialog->deleteLater());

dialog->init();

std::vector< std::pair<QString, QSize> > camerasInfo;
Expand Down Expand Up @@ -435,14 +440,22 @@ void ActionCommands::rotateCounterClockwise()

void ActionCommands::toggleMirror()
{
bool flipX = mEditor->view()->isFlipHorizontal();
mEditor->view()->flipHorizontal(!flipX);
BackupManager* backup = mEditor->backups();

bool flipX = !mEditor->view()->isFlipHorizontal();
mEditor->view()->flipHorizontal(flipX);

backup->flipView(flipX, DIRECTION::HORIZONTAL);
}

void ActionCommands::toggleMirrorV()
{
bool flipY = mEditor->view()->isFlipVertical();
mEditor->view()->flipVertical(!flipY);
BackupManager* backup = mEditor->backups();

bool flipY = !mEditor->view()->isFlipVertical();
mEditor->view()->flipVertical(flipY);

backup->flipView(flipY, DIRECTION::VERTICAL);
}

void ActionCommands::showGrid(bool bShow)
Expand Down Expand Up @@ -489,8 +502,11 @@ void ActionCommands::GotoPrevKeyFrame()

Status ActionCommands::addNewKey()
{
BackupManager* backups = mEditor->backups();

KeyFrame* key = mEditor->addNewKey();

backups->prepareBackup();
SoundClip* clip = dynamic_cast<SoundClip*>(key);
if (clip)
{
Expand All @@ -516,16 +532,23 @@ Status ActionCommands::addNewKey()
mEditor->view()->updateViewTransforms();
}

backups->keyAdded();
mEditor->layers()->notifyAnimationLengthChanged();

return Status::OK;
}

void ActionCommands::removeKey()
{
mEditor->removeKey();
BackupManager* backups = mEditor->backups();

Layer* layer = mEditor->layers()->currentLayer();

mEditor->backups()->prepareBackup();

mEditor->removeCurrentKey();

backups->keyRemoved();
if (layer->keyFrameCount() == 0)
{
layer->addNewKeyFrameAt(1);
Expand All @@ -534,6 +557,8 @@ void ActionCommands::removeKey()

void ActionCommands::duplicateKey()
{
BackupManager* backups = mEditor->backups();

Layer* layer = mEditor->layers()->currentLayer();
if (layer == NULL) return;

Expand All @@ -542,6 +567,7 @@ void ActionCommands::duplicateKey()

KeyFrame* dupKey = key->clone();

backups->prepareBackup();
int nextEmptyFrame = mEditor->currentFrame() + 1;
while (layer->keyExistsWhichCovers(nextEmptyFrame))
{
Expand All @@ -559,6 +585,7 @@ void ActionCommands::duplicateKey()
{
key->setFileName(""); // don't share filename
}
backups->keyAdded();

mEditor->layers()->notifyAnimationLengthChanged();
}
Expand Down Expand Up @@ -592,25 +619,35 @@ void ActionCommands::moveFrameBackward()
Status ActionCommands::addNewBitmapLayer()
{
bool ok;

BackupManager* backups = mEditor->backups();
backups->prepareBackup();

QString text = QInputDialog::getText(nullptr, tr("Layer Properties"),
tr("Layer name:"), QLineEdit::Normal,
tr("Bitmap Layer"), &ok);
if (ok && !text.isEmpty())
{
mEditor->layers()->createBitmapLayer(text);
backups->layerAdded();
}

return Status::OK;
}

Status ActionCommands::addNewVectorLayer()
{
bool ok;
BackupManager* backups = mEditor->backups();
backups->prepareBackup();

QString text = QInputDialog::getText(nullptr, tr("Layer Properties"),
tr("Layer name:"), QLineEdit::Normal,
tr("Vector Layer"), &ok);
if (ok && !text.isEmpty())
{
mEditor->layers()->createVectorLayer(text);
backups->layerAdded();
}

return Status::OK;
Expand All @@ -619,12 +656,16 @@ Status ActionCommands::addNewVectorLayer()
Status ActionCommands::addNewCameraLayer()
{
bool ok;
BackupManager* backups = mEditor->backups();
backups->prepareBackup();

QString text = QInputDialog::getText(nullptr, tr("Layer Properties"),
tr("Layer name:"), QLineEdit::Normal,
tr("Camera Layer"), &ok);
if (ok && !text.isEmpty())
{
mEditor->layers()->createCameraLayer(text);
backups->layerAdded();
}

return Status::OK;
Expand All @@ -633,6 +674,9 @@ Status ActionCommands::addNewCameraLayer()
Status ActionCommands::addNewSoundLayer()
{
bool ok = false;
BackupManager* backups = mEditor->backups();
backups->prepareBackup();

QString strLayerName = QInputDialog::getText(nullptr, tr("Layer Properties"),
tr("Layer name:"), QLineEdit::Normal,
tr("Sound Layer"), &ok);
Expand All @@ -641,6 +685,7 @@ Status ActionCommands::addNewSoundLayer()
Layer* layer = mEditor->layers()->createSoundLayer(strLayerName);
mEditor->layers()->setCurrentLayer(layer);

backups->layerAdded();
return Status::OK;
}
return Status::FAIL;
Expand All @@ -649,25 +694,63 @@ Status ActionCommands::addNewSoundLayer()
Status ActionCommands::deleteCurrentLayer()
{
LayerManager* layerMgr = mEditor->layers();
QString strLayerName = layerMgr->currentLayer()->name();
BackupManager* backups = mEditor->backups();
Layer* layer = mEditor->layers()->currentLayer();
QString layerName = layer->name();
int layerIndex = mEditor->currentLayerIndex();

backups->prepareBackup();
std::map<int, KeyFrame*, std::greater<int>> keyFrames;
for(auto map : layer->getKeysInLayer())
{
keyFrames.insert(std::make_pair(map.first, map.second->clone()));
}

int ret = QMessageBox::warning(mParent,
tr("Delete Layer", "Windows title of Delete current layer pop-up."),
tr("Are you sure you want to delete layer: ") + strLayerName + " ?",
tr("Are you sure you want to delete layer: ") + layerName + " ?",
QMessageBox::Ok | QMessageBox::Cancel,
QMessageBox::Ok);
if (ret == QMessageBox::Ok)
{
Status st = layerMgr->deleteLayer(mEditor->currentLayerIndex());
Status st = layerMgr->deleteLayer(layerIndex);
if (st == Status::ERROR_NEED_AT_LEAST_ONE_CAMERA_LAYER)
{
QMessageBox::information(mParent, "",
tr("Please keep at least one camera layer in project", "text when failed to delete camera layer"));
return Status::CANCELED;
}
backups->layerDeleted(keyFrames);
}
return Status::OK;
}

void ActionCommands::editCameraProperties()
{
CameraPropertiesDialog* dialog = nullptr;
LayerCamera* layer = static_cast<LayerCamera*>(mEditor->layers()->currentLayer());

QRect viewRect = layer->getViewRect();
mEditor->backups()->prepareBackup();

if ( dialog == NULL )
{
dialog = new CameraPropertiesDialog( layer->name(), viewRect.width(), viewRect.height() );
}
dialog->setName( layer->name() );
dialog->setWidth(viewRect.width());
dialog->setHeight(viewRect.height());
int result = dialog->exec();
if (result == QDialog::Accepted)
{
layer->setName( dialog->getName() );
layer->setViewRect(QRect(-dialog->getWidth()/2,
-dialog->getHeight()/2,
dialog->getWidth(),
dialog->getHeight()));
mEditor->backups()->cameraProperties(viewRect);
}
}

void ActionCommands::help()
{
Expand Down
4 changes: 3 additions & 1 deletion app/src/actioncommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,20 @@ class ActionCommands : public QObject
void GotoPrevFrame();
void GotoNextKeyFrame();
void GotoPrevKeyFrame();
Status addNewKey();
void removeKey();
void duplicateKey();
void moveFrameForward();
void moveFrameBackward();

Status addNewKey();

// Layer
Status addNewBitmapLayer();
Status addNewVectorLayer();
Status addNewCameraLayer();
Status addNewSoundLayer();
Status deleteCurrentLayer();
void editCameraProperties();

// Help
void help();
Expand Down
26 changes: 26 additions & 0 deletions app/src/displayoptionwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@ GNU General Public License for more details.
#include <QGridLayout>

#include "preferencemanager.h"
#include "backupmanager.h"
#include "viewmanager.h"
#include "scribblearea.h"

#include "editor.h"
#include "util.h"
#include "direction.h"


DisplayOptionWidget::DisplayOptionWidget(QWidget *parent) :
Expand Down Expand Up @@ -108,34 +111,57 @@ void DisplayOptionWidget::updateUI()

void DisplayOptionWidget::onionPrevButtonClicked(bool isOn)
{
// BackupManager* backup = editor()->backups();

PreferenceManager* prefs = editor()->preference();
prefs->set(SETTING::PREV_ONION, isOn);

// backup->toggleSetting(isOn, SETTING::PREV_ONION);

}

void DisplayOptionWidget::onionNextButtonClicked(bool isOn)
{
// BackupManager* backup = editor()->backups();

PreferenceManager* prefs = editor()->preference();
prefs->set(SETTING::NEXT_ONION, isOn);

// backup->toggleSetting(isOn, SETTING::NEXT_ONION);
}

void DisplayOptionWidget::onionBlueButtonClicked(bool isOn)
{
// BackupManager* backup = editor()->backups();

PreferenceManager* prefs = editor()->preference();
prefs->set(SETTING::ONION_BLUE, isOn);

// backup->toggleSetting(isOn, SETTING::ONION_BLUE);
}

void DisplayOptionWidget::onionRedButtonClicked(bool isOn)
{
// BackupManager* backup = editor()->backups();

PreferenceManager* prefs = editor()->preference();
prefs->set(SETTING::ONION_RED, isOn);

// backup->toggleSetting(isOn, SETTING::ONION_RED);
}

void DisplayOptionWidget::toggleMirror(bool isOn)
{
// BackupManager* backup = editor()->backups();
editor()->view()->flipHorizontal(isOn);

// backup->flipView(isOn, DIRECTION::HORIZONTAL);
}

void DisplayOptionWidget::toggleMirrorV(bool isOn)
{
// BackupManager* backup = editor()->backups();
editor()->view()->flipVertical(isOn);

// backup->flipView(isOn, DIRECTION::VERTICAL);
}
Loading