diff --git a/Applications/PixelPaint/CMakeLists.txt b/Applications/PixelPaint/CMakeLists.txt index 44df93980f..73e2196ca7 100644 --- a/Applications/PixelPaint/CMakeLists.txt +++ b/Applications/PixelPaint/CMakeLists.txt @@ -5,7 +5,6 @@ set(SOURCES CreateNewLayerDialog.cpp EllipseTool.cpp EraseTool.cpp - History.cpp Image.cpp ImageEditor.cpp Layer.cpp diff --git a/Applications/PixelPaint/History.cpp b/Applications/PixelPaint/History.cpp deleted file mode 100644 index 2295a85bfe..0000000000 --- a/Applications/PixelPaint/History.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2020, Ben Jilks - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "History.h" -#include "Image.h" -#include "Layer.h" -#include -#include - -namespace PixelPaint { - -void History::on_action(const Image& image) -{ - m_snapshots.shrink(m_snapshots.size() - m_current_index_back_into_history); - m_current_index_back_into_history = 0; - m_snapshots.append(image.take_snapshot()); - if (m_snapshots.size() > s_max_size) - m_snapshots.take_first(); -} - -bool History::undo(Image& image) -{ - if (m_snapshots.size() - m_current_index_back_into_history - 1 <= 0) - return false; - - m_current_index_back_into_history += 1; - const Image& last_snapshot = *m_snapshots[m_snapshots.size() - m_current_index_back_into_history - 1]; - image.restore_snapshot(last_snapshot); - return true; -} - -bool History::redo(Image& image) -{ - if (m_current_index_back_into_history <= 0) - return false; - - const Image& last_snapshot = *m_snapshots[m_snapshots.size() - m_current_index_back_into_history]; - m_current_index_back_into_history -= 1; - image.restore_snapshot(last_snapshot); - return true; -} - -void History::reset(const Image& image) -{ - m_snapshots.clear(); - m_current_index_back_into_history = 0; - on_action(image); -} - -} diff --git a/Applications/PixelPaint/History.h b/Applications/PixelPaint/History.h deleted file mode 100644 index f2ec352ff2..0000000000 --- a/Applications/PixelPaint/History.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2020, Ben Jilks - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#include -#include - -namespace PixelPaint { - -class Image; - -class History { - AK_MAKE_NONCOPYABLE(History); - AK_MAKE_NONMOVABLE(History); - -public: - History() = default; - - void on_action(const Image&); - bool undo(Image&); - bool redo(Image&); - void reset(const Image&); - -private: - static constexpr int s_max_size = 50; - Vector> m_snapshots; - int m_current_index_back_into_history { 0 }; -}; - -} diff --git a/Applications/PixelPaint/Image.cpp b/Applications/PixelPaint/Image.cpp index 23a7f89d7e..c130998e7c 100644 --- a/Applications/PixelPaint/Image.cpp +++ b/Applications/PixelPaint/Image.cpp @@ -312,4 +312,20 @@ void Image::did_change() client->image_did_change(); } +ImageUndoCommand::ImageUndoCommand(Image& image) + : m_snapshot(image.take_snapshot()) + , m_image(image) +{ +} + +void ImageUndoCommand::undo() +{ + m_image.restore_snapshot(*m_snapshot); +} + +void ImageUndoCommand::redo() +{ + undo(); +} + } diff --git a/Applications/PixelPaint/Image.h b/Applications/PixelPaint/Image.h index c4a25b54b2..63184b3ad3 100644 --- a/Applications/PixelPaint/Image.h +++ b/Applications/PixelPaint/Image.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -98,4 +99,16 @@ private: HashTable m_clients; }; +class ImageUndoCommand : public GUI::Command { +public: + ImageUndoCommand(Image& image); + + virtual void undo() override; + virtual void redo() override; + +private: + RefPtr m_snapshot; + Image& m_image; +}; + } diff --git a/Applications/PixelPaint/ImageEditor.cpp b/Applications/PixelPaint/ImageEditor.cpp index 3c769cbd8b..33b8b8b713 100644 --- a/Applications/PixelPaint/ImageEditor.cpp +++ b/Applications/PixelPaint/ImageEditor.cpp @@ -28,6 +28,7 @@ #include "Image.h" #include "Layer.h" #include "Tool.h" +#include #include #include #include @@ -35,6 +36,7 @@ namespace PixelPaint { ImageEditor::ImageEditor() + : m_undo_stack(make()) { set_focus_policy(GUI::FocusPolicy::StrongFocus); } @@ -52,7 +54,8 @@ void ImageEditor::set_image(RefPtr image) m_image = move(image); m_active_layer = nullptr; - m_history.reset(*m_image); + m_undo_stack = make(); + m_undo_stack->push(make(*m_image)); update(); relayout(); @@ -64,14 +67,16 @@ void ImageEditor::did_complete_action() { if (!m_image) return; - m_history.on_action(*m_image); + m_undo_stack->finalize_current_combo(); + m_undo_stack->push(make(*m_image)); } bool ImageEditor::undo() { if (!m_image) return false; - if (m_history.undo(*m_image)) { + if (m_undo_stack->can_undo()) { + m_undo_stack->undo(); layers_did_change(); return true; } @@ -82,7 +87,8 @@ bool ImageEditor::redo() { if (!m_image) return false; - if (m_history.redo(*m_image)) { + if (m_undo_stack->can_redo()) { + m_undo_stack->redo(); layers_did_change(); return true; } diff --git a/Applications/PixelPaint/ImageEditor.h b/Applications/PixelPaint/ImageEditor.h index 0873cd5c1c..b6cdc8fb62 100644 --- a/Applications/PixelPaint/ImageEditor.h +++ b/Applications/PixelPaint/ImageEditor.h @@ -26,9 +26,9 @@ #pragma once -#include "History.h" #include "Image.h" #include +#include #include namespace PixelPaint { @@ -108,7 +108,7 @@ private: RefPtr m_image; RefPtr m_active_layer; - History m_history; + OwnPtr m_undo_stack; Tool* m_active_tool { nullptr };