mirror of
https://github.com/RGBCube/serenity
synced 2025-05-30 19:38:12 +00:00
PixelPaint: Use UndoStack instead of History
This allows to share more code with other undo systems.
This commit is contained in:
parent
7707ebcd63
commit
a27d118085
7 changed files with 41 additions and 134 deletions
|
@ -5,7 +5,6 @@ set(SOURCES
|
||||||
CreateNewLayerDialog.cpp
|
CreateNewLayerDialog.cpp
|
||||||
EllipseTool.cpp
|
EllipseTool.cpp
|
||||||
EraseTool.cpp
|
EraseTool.cpp
|
||||||
History.cpp
|
|
||||||
Image.cpp
|
Image.cpp
|
||||||
ImageEditor.cpp
|
ImageEditor.cpp
|
||||||
Layer.cpp
|
Layer.cpp
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020, Ben Jilks <benjyjilks@gmail.com>
|
|
||||||
* 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 <AK/LogStream.h>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020, Ben Jilks <benjyjilks@gmail.com>
|
|
||||||
* 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 <AK/String.h>
|
|
||||||
#include <AK/Vector.h>
|
|
||||||
|
|
||||||
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<RefPtr<Image>> m_snapshots;
|
|
||||||
int m_current_index_back_into_history { 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -312,4 +312,20 @@ void Image::did_change()
|
||||||
client->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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <AK/RefCounted.h>
|
#include <AK/RefCounted.h>
|
||||||
#include <AK/RefPtr.h>
|
#include <AK/RefPtr.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
#include <LibGUI/Command.h>
|
||||||
#include <LibGUI/Forward.h>
|
#include <LibGUI/Forward.h>
|
||||||
#include <LibGfx/Forward.h>
|
#include <LibGfx/Forward.h>
|
||||||
#include <LibGfx/Rect.h>
|
#include <LibGfx/Rect.h>
|
||||||
|
@ -98,4 +99,16 @@ private:
|
||||||
HashTable<ImageClient*> m_clients;
|
HashTable<ImageClient*> m_clients;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ImageUndoCommand : public GUI::Command {
|
||||||
|
public:
|
||||||
|
ImageUndoCommand(Image& image);
|
||||||
|
|
||||||
|
virtual void undo() override;
|
||||||
|
virtual void redo() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
RefPtr<Image> m_snapshot;
|
||||||
|
Image& m_image;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
#include "Layer.h"
|
#include "Layer.h"
|
||||||
#include "Tool.h"
|
#include "Tool.h"
|
||||||
|
#include <LibGUI/Command.h>
|
||||||
#include <LibGUI/Painter.h>
|
#include <LibGUI/Painter.h>
|
||||||
#include <LibGfx/Palette.h>
|
#include <LibGfx/Palette.h>
|
||||||
#include <LibGfx/Rect.h>
|
#include <LibGfx/Rect.h>
|
||||||
|
@ -35,6 +36,7 @@
|
||||||
namespace PixelPaint {
|
namespace PixelPaint {
|
||||||
|
|
||||||
ImageEditor::ImageEditor()
|
ImageEditor::ImageEditor()
|
||||||
|
: m_undo_stack(make<GUI::UndoStack>())
|
||||||
{
|
{
|
||||||
set_focus_policy(GUI::FocusPolicy::StrongFocus);
|
set_focus_policy(GUI::FocusPolicy::StrongFocus);
|
||||||
}
|
}
|
||||||
|
@ -52,7 +54,8 @@ void ImageEditor::set_image(RefPtr<Image> image)
|
||||||
|
|
||||||
m_image = move(image);
|
m_image = move(image);
|
||||||
m_active_layer = nullptr;
|
m_active_layer = nullptr;
|
||||||
m_history.reset(*m_image);
|
m_undo_stack = make<GUI::UndoStack>();
|
||||||
|
m_undo_stack->push(make<ImageUndoCommand>(*m_image));
|
||||||
update();
|
update();
|
||||||
relayout();
|
relayout();
|
||||||
|
|
||||||
|
@ -64,14 +67,16 @@ void ImageEditor::did_complete_action()
|
||||||
{
|
{
|
||||||
if (!m_image)
|
if (!m_image)
|
||||||
return;
|
return;
|
||||||
m_history.on_action(*m_image);
|
m_undo_stack->finalize_current_combo();
|
||||||
|
m_undo_stack->push(make<ImageUndoCommand>(*m_image));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImageEditor::undo()
|
bool ImageEditor::undo()
|
||||||
{
|
{
|
||||||
if (!m_image)
|
if (!m_image)
|
||||||
return false;
|
return false;
|
||||||
if (m_history.undo(*m_image)) {
|
if (m_undo_stack->can_undo()) {
|
||||||
|
m_undo_stack->undo();
|
||||||
layers_did_change();
|
layers_did_change();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +87,8 @@ bool ImageEditor::redo()
|
||||||
{
|
{
|
||||||
if (!m_image)
|
if (!m_image)
|
||||||
return false;
|
return false;
|
||||||
if (m_history.redo(*m_image)) {
|
if (m_undo_stack->can_redo()) {
|
||||||
|
m_undo_stack->redo();
|
||||||
layers_did_change();
|
layers_did_change();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "History.h"
|
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
#include <LibGUI/Frame.h>
|
#include <LibGUI/Frame.h>
|
||||||
|
#include <LibGUI/UndoStack.h>
|
||||||
#include <LibGfx/Point.h>
|
#include <LibGfx/Point.h>
|
||||||
|
|
||||||
namespace PixelPaint {
|
namespace PixelPaint {
|
||||||
|
@ -108,7 +108,7 @@ private:
|
||||||
|
|
||||||
RefPtr<Image> m_image;
|
RefPtr<Image> m_image;
|
||||||
RefPtr<Layer> m_active_layer;
|
RefPtr<Layer> m_active_layer;
|
||||||
History m_history;
|
OwnPtr<GUI::UndoStack> m_undo_stack;
|
||||||
|
|
||||||
Tool* m_active_tool { nullptr };
|
Tool* m_active_tool { nullptr };
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue