mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-23 18:39:55 +00:00
Implement Undo limit (fix #1127)
This commit is contained in:
parent
363341ad34
commit
f0c11ef567
@ -141,6 +141,21 @@ private:
|
||||
actions()->selectChild(item);
|
||||
}
|
||||
|
||||
void onDeleteUndoState(DocumentUndo* history,
|
||||
undo::UndoState* state) override {
|
||||
for (auto child : actions()->children()) {
|
||||
Item* item = static_cast<Item*>(child);
|
||||
if (item->state() == state) {
|
||||
actions()->removeChild(item);
|
||||
item->deferDelete();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
actions()->layout();
|
||||
view()->updateView();
|
||||
}
|
||||
|
||||
void onAfterUndo(DocumentUndo* history) override {
|
||||
selectState(history->currentState());
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
// Copyright (C) 2001-2017 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -15,6 +15,7 @@
|
||||
#include "app/cmd_transaction.h"
|
||||
#include "app/document_undo_observer.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "base/mem_utils.h"
|
||||
#include "doc/context.h"
|
||||
#include "undo/undo_history.h"
|
||||
#include "undo/undo_state.h"
|
||||
@ -22,10 +23,14 @@
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
#define UNDO_TRACE(...)
|
||||
|
||||
namespace app {
|
||||
|
||||
DocumentUndo::DocumentUndo()
|
||||
: m_ctx(NULL)
|
||||
: m_undoHistory(this)
|
||||
, m_ctx(nullptr)
|
||||
, m_totalUndoSize(0)
|
||||
, m_savedCounter(0)
|
||||
, m_savedStateIsLost(false)
|
||||
{
|
||||
@ -39,6 +44,10 @@ void DocumentUndo::setContext(doc::Context* ctx)
|
||||
void DocumentUndo::add(CmdTransaction* cmd)
|
||||
{
|
||||
ASSERT(cmd);
|
||||
UNDO_TRACE("UNDO: Add state <%s> of %s to %s\n",
|
||||
cmd->label().c_str(),
|
||||
base::get_pretty_memory_size(cmd->memSize()).c_str(),
|
||||
base::get_pretty_memory_size(m_totalUndoSize).c_str());
|
||||
|
||||
// A linear undo history is the default behavior
|
||||
if (!App::instance() ||
|
||||
@ -47,7 +56,33 @@ void DocumentUndo::add(CmdTransaction* cmd)
|
||||
}
|
||||
|
||||
m_undoHistory.add(cmd);
|
||||
m_totalUndoSize += cmd->memSize();
|
||||
|
||||
notify_observers(&DocumentUndoObserver::onAddUndoState, this);
|
||||
|
||||
if (App::instance()) {
|
||||
const size_t undoLimitSize =
|
||||
int(App::instance()->preferences().undo.sizeLimit())
|
||||
* 1024 * 1024;
|
||||
|
||||
// If undo limit is 0, it means "no limit", so we ignore the
|
||||
// complete logic to discard undo states.
|
||||
if (undoLimitSize > 0 &&
|
||||
m_totalUndoSize > undoLimitSize) {
|
||||
UNDO_TRACE("UNDO: Reducing undo history from %s to %s\n",
|
||||
base::get_pretty_memory_size(m_totalUndoSize).c_str(),
|
||||
base::get_pretty_memory_size(undoLimitSize).c_str());
|
||||
|
||||
while (m_undoHistory.firstState() &&
|
||||
m_totalUndoSize > undoLimitSize) {
|
||||
if (!m_undoHistory.deleteFirstState())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UNDO_TRACE("UNDO: New undo size %s\n",
|
||||
base::get_pretty_memory_size(m_totalUndoSize).c_str());
|
||||
}
|
||||
|
||||
bool DocumentUndo::canUndo() const
|
||||
@ -160,4 +195,17 @@ const undo::UndoState* DocumentUndo::nextRedo() const
|
||||
return m_undoHistory.firstState();
|
||||
}
|
||||
|
||||
void DocumentUndo::onDeleteUndoState(undo::UndoState* state)
|
||||
{
|
||||
Cmd* cmd = static_cast<Cmd*>(state->cmd());
|
||||
|
||||
UNDO_TRACE("UNDO: Deleting undo state <%s> of %s from %s\n",
|
||||
cmd->label().c_str(),
|
||||
base::get_pretty_memory_size(cmd->memSize()).c_str(),
|
||||
base::get_pretty_memory_size(m_totalUndoSize).c_str());
|
||||
|
||||
m_totalUndoSize -= cmd->memSize();
|
||||
notify_observers(&DocumentUndoObserver::onDeleteUndoState, this, state);
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
// Copyright (C) 2001-2017 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -27,7 +27,8 @@ namespace app {
|
||||
class CmdTransaction;
|
||||
class DocumentUndoObserver;
|
||||
|
||||
class DocumentUndo : public obs::observable<DocumentUndoObserver> {
|
||||
class DocumentUndo : public obs::observable<DocumentUndoObserver>,
|
||||
public undo::UndoHistoryDelegate {
|
||||
public:
|
||||
DocumentUndo();
|
||||
|
||||
@ -65,8 +66,12 @@ namespace app {
|
||||
const undo::UndoState* nextUndo() const;
|
||||
const undo::UndoState* nextRedo() const;
|
||||
|
||||
// undo::UndoHistoryDelegate impl
|
||||
void onDeleteUndoState(undo::UndoState* state) override;
|
||||
|
||||
undo::UndoHistory m_undoHistory;
|
||||
doc::Context* m_ctx;
|
||||
size_t m_totalUndoSize;
|
||||
|
||||
// This counter is equal to 0 if we are in the "saved state", i.e.
|
||||
// the document on memory is equal to the document on disk. This
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2015 David Capello
|
||||
// Copyright (C) 2015-2017 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -20,6 +20,8 @@ class DocumentUndo;
|
||||
public:
|
||||
virtual ~DocumentUndoObserver() { }
|
||||
virtual void onAddUndoState(DocumentUndo* history) = 0;
|
||||
virtual void onDeleteUndoState(DocumentUndo* history,
|
||||
undo::UndoState* state) = 0;
|
||||
virtual void onAfterUndo(DocumentUndo* history) = 0;
|
||||
virtual void onAfterRedo(DocumentUndo* history) = 0;
|
||||
virtual void onClearRedo(DocumentUndo* history) = 0;
|
||||
|
@ -1769,8 +1769,10 @@ void Timeline::drawHeaderFrame(ui::Graphics* g, frame_t frame)
|
||||
return;
|
||||
|
||||
// Draw the header for the layers.
|
||||
std::string text = base::convert_to<std::string, int>(
|
||||
(docPref().timeline.firstFrame()+frame) % 100);
|
||||
const int n = (docPref().timeline.firstFrame()+frame);
|
||||
std::string text = base::convert_to<std::string, int>(n % 100);
|
||||
if (n >= 100 && (n % 100) < 10)
|
||||
text.insert(0, 1, '0');
|
||||
|
||||
drawPart(g, bounds, &text,
|
||||
skinTheme()->styles.timelineHeaderFrame(),
|
||||
|
2
src/undo
2
src/undo
@ -1 +1 @@
|
||||
Subproject commit f39b188e29d0f9adaa49c8705c0f492939d967a9
|
||||
Subproject commit f17044afa2632bb2f3c21509bd064cbfa891e653
|
Loading…
x
Reference in New Issue
Block a user