mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-29 19:20:09 +00:00
Generate selection boundaries automatically after transactions
Now Transaction::commit() will regenerate mask boundaries automatically if in the middle of the transaction the document selection was modified. This is the first step to finally remove update_screen_for_document() and any kind of manual screen refresh. This will be useful for scripting functions that modify the selection too, because we wouldn't need to regenerate the selection boundaries automatically from the script or from app.refresh() Lua function. Related to #378
This commit is contained in:
parent
668b29193a
commit
7594ebf25b
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -27,6 +28,7 @@ void DeselectMask::onExecute()
|
||||
Doc* doc = document();
|
||||
m_oldMask.reset(doc->isMaskVisible() ? new Mask(*doc->mask()): nullptr);
|
||||
doc->setMaskVisible(false);
|
||||
doc->notifySelectionChanged();
|
||||
}
|
||||
|
||||
void DeselectMask::onUndo()
|
||||
@ -35,6 +37,7 @@ void DeselectMask::onUndo()
|
||||
|
||||
doc->setMask(m_oldMask.get());
|
||||
doc->setMaskVisible(true);
|
||||
doc->notifySelectionChanged();
|
||||
|
||||
m_oldMask.reset();
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -37,8 +38,8 @@ void FlipMask::onUndo()
|
||||
|
||||
void FlipMask::swap()
|
||||
{
|
||||
Doc* document = this->document();
|
||||
Mask* mask = document->mask();
|
||||
Doc* doc = this->document();
|
||||
Mask* mask = doc->mask();
|
||||
|
||||
ASSERT(mask->bitmap());
|
||||
if (!mask->bitmap())
|
||||
@ -48,6 +49,8 @@ void FlipMask::swap()
|
||||
doc::algorithm::flip_image(mask->bitmap(),
|
||||
mask->bitmap()->bounds(), m_flipType);
|
||||
mask->unfreeze();
|
||||
|
||||
doc->notifySelectionChanged();
|
||||
}
|
||||
|
||||
} // namespace cmd
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -32,6 +33,7 @@ void ReselectMask::onExecute()
|
||||
}
|
||||
|
||||
doc->setMaskVisible(true);
|
||||
doc->notifySelectionChanged();
|
||||
}
|
||||
|
||||
void ReselectMask::onUndo()
|
||||
@ -41,6 +43,7 @@ void ReselectMask::onUndo()
|
||||
m_oldMask.reset(doc->isMaskVisible() ? new Mask(*doc->mask()): nullptr);
|
||||
|
||||
doc->setMaskVisible(false);
|
||||
doc->notifySelectionChanged();
|
||||
}
|
||||
|
||||
size_t ReselectMask::onMemSize() const
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -16,14 +17,14 @@
|
||||
namespace app {
|
||||
namespace cmd {
|
||||
|
||||
SetMask::SetMask(Doc* doc, Mask* newMask)
|
||||
SetMask::SetMask(Doc* doc, const Mask* newMask)
|
||||
: WithDocument(doc)
|
||||
, m_oldMask(doc->isMaskVisible() ? new Mask(*doc->mask()): nullptr)
|
||||
, m_newMask(newMask && !newMask->isEmpty() ? new Mask(*newMask): nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void SetMask::setNewMask(Mask* newMask)
|
||||
void SetMask::setNewMask(const Mask* newMask)
|
||||
{
|
||||
m_newMask.reset(newMask ? new Mask(*newMask): nullptr);
|
||||
setMask(m_newMask.get());
|
||||
@ -46,7 +47,7 @@ size_t SetMask::onMemSize() const
|
||||
(m_newMask ? m_newMask->getMemSize(): 0);
|
||||
}
|
||||
|
||||
void SetMask::setMask(Mask* mask)
|
||||
void SetMask::setMask(const Mask* mask)
|
||||
{
|
||||
Doc* doc = document();
|
||||
|
||||
@ -59,6 +60,8 @@ void SetMask::setMask(Mask* mask)
|
||||
doc->setMask(&empty);
|
||||
doc->setMaskVisible(false);
|
||||
}
|
||||
|
||||
doc->notifySelectionChanged();
|
||||
}
|
||||
|
||||
} // namespace cmd
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -25,10 +26,10 @@ namespace cmd {
|
||||
class SetMask : public Cmd
|
||||
, public WithDocument {
|
||||
public:
|
||||
SetMask(Doc* doc, Mask* newMask);
|
||||
SetMask(Doc* doc, const Mask* newMask);
|
||||
|
||||
// Used to change the new mask used in the onRedo()
|
||||
void setNewMask(Mask* newMask);
|
||||
void setNewMask(const Mask* newMask);
|
||||
|
||||
protected:
|
||||
void onExecute() override;
|
||||
@ -36,7 +37,7 @@ namespace cmd {
|
||||
size_t onMemSize() const override;
|
||||
|
||||
private:
|
||||
void setMask(Mask* mask);
|
||||
void setMask(const Mask* mask);
|
||||
|
||||
std::unique_ptr<Mask> m_oldMask;
|
||||
std::unique_ptr<Mask> m_newMask;
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -38,6 +39,8 @@ void SetMaskPosition::setMaskPosition(const gfx::Point& pos)
|
||||
Doc* doc = document();
|
||||
doc->mask()->setOrigin(pos.x, pos.y);
|
||||
doc->resetTransformation();
|
||||
|
||||
doc->notifySelectionChanged();
|
||||
}
|
||||
|
||||
} // namespace cmd
|
||||
|
@ -352,8 +352,6 @@ void CanvasSizeCommand::onExecute(Context* context)
|
||||
MID(1, y2-y1, DOC_SPRITE_MAX_HEIGHT)));
|
||||
tx.commit();
|
||||
|
||||
doc->generateMaskBoundaries();
|
||||
|
||||
#ifdef ENABLE_UI
|
||||
if (context->isUIAvailable())
|
||||
update_screen_for_document(doc);
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -74,7 +75,6 @@ void CropSpriteCommand::onExecute(Context* context)
|
||||
document->getApi(tx).cropSprite(sprite, bounds);
|
||||
tx.commit();
|
||||
}
|
||||
document->generateMaskBoundaries();
|
||||
|
||||
#ifdef ENABLE_UI
|
||||
if (context->isUIAvailable())
|
||||
@ -112,7 +112,6 @@ void AutocropSpriteCommand::onExecute(Context* context)
|
||||
document->getApi(tx).trimSprite(sprite);
|
||||
tx.commit();
|
||||
}
|
||||
document->generateMaskBoundaries();
|
||||
|
||||
#ifdef ENABLE_UI
|
||||
if (context->isUIAvailable())
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -47,7 +48,6 @@ void DeselectMaskCommand::onExecute(Context* context)
|
||||
tx(new cmd::DeselectMask(document));
|
||||
tx.commit();
|
||||
}
|
||||
document->generateMaskBoundaries();
|
||||
update_screen_for_document(document);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -222,8 +223,6 @@ void FlipCommand::onExecute(Context* context)
|
||||
(m_flipType == doc::algorithm::FlipVertical ?
|
||||
sprite->height() - mask->bounds().y2():
|
||||
mask->bounds().y))));
|
||||
|
||||
document->generateMaskBoundaries();
|
||||
}
|
||||
|
||||
tx.commit();
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -96,7 +97,6 @@ void InvertMaskCommand::onExecute(Context* context)
|
||||
tx(new cmd::SetMask(document, mask.get()));
|
||||
tx.commit();
|
||||
|
||||
document->generateMaskBoundaries();
|
||||
update_screen_for_document(document);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -80,7 +81,6 @@ void LoadMaskCommand::onExecute(Context* context)
|
||||
tx(new cmd::SetMask(document, mask.get()));
|
||||
tx.commit();
|
||||
|
||||
document->generateMaskBoundaries();
|
||||
update_screen_for_document(document);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -50,10 +51,8 @@ void MaskAllCommand::onExecute(Context* context)
|
||||
|
||||
Tx tx(writer.context(), "Select All", DoesntModifyDocument);
|
||||
tx(new cmd::SetMask(document, &newMask));
|
||||
tx.commit();
|
||||
|
||||
document->resetTransformation();
|
||||
document->generateMaskBoundaries();
|
||||
tx.commit();
|
||||
|
||||
if (Preferences::instance().selection.autoShowSelectionEdges()) {
|
||||
DocumentPreferences& docPref = Preferences::instance().document(document);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -189,9 +189,11 @@ void MaskByColorCommand::onExecute(Context* context)
|
||||
set_config_int("MaskColor", "Tolerance", m_sliderTolerance->getValue());
|
||||
set_config_bool("MaskColor", "Preview", m_checkPreview->isSelected());
|
||||
}
|
||||
else {
|
||||
document->generateMaskBoundaries();
|
||||
}
|
||||
|
||||
// Update boundaries and editors.
|
||||
document->generateMaskBoundaries();
|
||||
update_screen_for_document(document);
|
||||
|
||||
// Save window configuration.
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -83,10 +84,8 @@ void MaskContentCommand::onExecute(Context* context)
|
||||
|
||||
Tx tx(writer.context(), "Select Content", DoesntModifyDocument);
|
||||
tx(new cmd::SetMask(document, &newMask));
|
||||
tx.commit();
|
||||
|
||||
document->resetTransformation();
|
||||
document->generateMaskBoundaries();
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
// Select marquee tool
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2015-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -143,7 +144,6 @@ void ModifySelectionCommand::onExecute(Context* context)
|
||||
tx(new cmd::SetMask(document, mask.get()));
|
||||
tx.commit();
|
||||
|
||||
document->generateMaskBoundaries();
|
||||
update_screen_for_document(document);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -88,7 +89,6 @@ void MoveMaskCommand::onExecute(Context* context)
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
document->generateMaskBoundaries();
|
||||
update_screen_for_document(document);
|
||||
break;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -53,7 +54,6 @@ void ReselectMaskCommand::onExecute(Context* context)
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
document->generateMaskBoundaries();
|
||||
update_screen_for_document(document);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -243,7 +244,6 @@ void RotateCommand::onExecute(Context* context)
|
||||
job.startJob();
|
||||
job.waitJob();
|
||||
}
|
||||
reader.document()->generateMaskBoundaries();
|
||||
update_screen_for_document(reader.document());
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
||||
// Copyright (C) 2015-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -109,7 +109,6 @@ void SelectTileCommand::onExecute(Context* ctx)
|
||||
tx(new cmd::SetMask(doc, mask.get()));
|
||||
tx.commit();
|
||||
|
||||
doc->generateMaskBoundaries();
|
||||
update_screen_for_document(doc);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -180,6 +180,12 @@ void Doc::notifySelectionChanged()
|
||||
notify_observers<DocEvent&>(&DocObserver::onSelectionChanged, ev);
|
||||
}
|
||||
|
||||
void Doc::notifySelectionBoundariesChanged()
|
||||
{
|
||||
DocEvent ev(this);
|
||||
notify_observers<DocEvent&>(&DocObserver::onSelectionBoundariesChanged, ev);
|
||||
}
|
||||
|
||||
bool Doc::isModified() const
|
||||
{
|
||||
return !m_undo->isSavedState();
|
||||
@ -252,8 +258,7 @@ void Doc::generateMaskBoundaries(const Mask* mask)
|
||||
mask->bounds().y);
|
||||
}
|
||||
|
||||
// TODO move this to the exact place where selection is modified.
|
||||
notifySelectionChanged();
|
||||
notifySelectionBoundariesChanged();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -261,7 +266,9 @@ void Doc::generateMaskBoundaries(const Mask* mask)
|
||||
|
||||
void Doc::setMask(const Mask* mask)
|
||||
{
|
||||
m_mask.reset(new Mask(*mask));
|
||||
ASSERT(mask);
|
||||
|
||||
m_mask->copyFrom(mask);
|
||||
m_flags |= kMaskVisible;
|
||||
|
||||
resetTransformation();
|
||||
@ -271,7 +278,6 @@ bool Doc::isMaskVisible() const
|
||||
{
|
||||
return
|
||||
(m_flags & kMaskVisible) && // The mask was not hidden by the user explicitly
|
||||
m_mask && // The mask does exist
|
||||
!m_mask->isEmpty(); // The mask is not empty
|
||||
}
|
||||
|
||||
@ -298,10 +304,7 @@ void Doc::setTransformation(const Transformation& transform)
|
||||
|
||||
void Doc::resetTransformation()
|
||||
{
|
||||
if (m_mask)
|
||||
m_transformation = Transformation(gfx::RectF(m_mask->bounds()));
|
||||
else
|
||||
m_transformation = Transformation();
|
||||
m_transformation = Transformation(gfx::RectF(m_mask->bounds()));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -96,6 +96,7 @@ namespace app {
|
||||
void notifyCelMoved(Layer* fromLayer, frame_t fromFrame, Layer* toLayer, frame_t toFrame);
|
||||
void notifyCelCopied(Layer* fromLayer, frame_t fromFrame, Layer* toLayer, frame_t toFrame);
|
||||
void notifySelectionChanged();
|
||||
void notifySelectionBoundariesChanged();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// File related properties
|
||||
@ -211,7 +212,7 @@ namespace app {
|
||||
ExtraCelRef m_extraCel;
|
||||
|
||||
// Current mask.
|
||||
std::unique_ptr<Mask> m_mask;
|
||||
std::unique_ptr<doc::Mask> m_mask;
|
||||
|
||||
// Current transformation.
|
||||
Transformation m_transformation;
|
||||
|
@ -68,6 +68,7 @@ namespace app {
|
||||
|
||||
// The selection has changed.
|
||||
virtual void onSelectionChanged(DocEvent& ev) { }
|
||||
virtual void onSelectionBoundariesChanged(DocEvent& ev) { }
|
||||
|
||||
// Called to destroy the observable. (Here you could call "delete this".)
|
||||
virtual void dispose() { }
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -16,6 +16,7 @@
|
||||
#include "app/doc.h"
|
||||
#include "app/doc_undo.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "ui/system.h"
|
||||
|
||||
#define TX_TRACE(...)
|
||||
|
||||
@ -25,17 +26,22 @@ using namespace doc;
|
||||
|
||||
Transaction::Transaction(Context* ctx, const std::string& label, Modification modification)
|
||||
: m_ctx(ctx)
|
||||
, m_cmds(NULL)
|
||||
, m_doc(nullptr)
|
||||
, m_undo(nullptr)
|
||||
, m_cmds(nullptr)
|
||||
, m_changes(Changes::kNone)
|
||||
{
|
||||
TX_TRACE("TX: Start <%s> (%s)\n",
|
||||
label.c_str(),
|
||||
modification == ModifyDocument ? "modifies document":
|
||||
"doesn't modify document");
|
||||
|
||||
Doc* doc = m_ctx->activeDocument();
|
||||
if (!doc)
|
||||
m_doc = m_ctx->activeDocument();
|
||||
if (!m_doc)
|
||||
throw std::runtime_error("No active document to execute a transaction");
|
||||
m_undo = doc->undoHistory();
|
||||
|
||||
m_doc->add_observer(this);
|
||||
m_undo = m_doc->undoHistory();
|
||||
|
||||
m_cmds = new CmdTransaction(label,
|
||||
modification == Modification::ModifyDocument,
|
||||
@ -60,6 +66,8 @@ Transaction::~Transaction()
|
||||
|
||||
// TODO logging error
|
||||
}
|
||||
|
||||
m_doc->remove_observer(this);
|
||||
}
|
||||
|
||||
// Used to set the document range after all the transaction is
|
||||
@ -73,12 +81,17 @@ void Transaction::setNewDocRange(const DocRange& range)
|
||||
|
||||
void Transaction::commit()
|
||||
{
|
||||
ui::assert_ui_thread();
|
||||
ASSERT(m_cmds);
|
||||
TX_TRACE("TX: Commit <%s>\n", m_cmds->label().c_str());
|
||||
|
||||
m_cmds->commit();
|
||||
m_undo->add(m_cmds);
|
||||
m_cmds = NULL;
|
||||
m_cmds = nullptr;
|
||||
|
||||
// Process changes
|
||||
if (int(m_changes) & int(Changes::kSelection))
|
||||
m_doc->generateMaskBoundaries();
|
||||
}
|
||||
|
||||
void Transaction::rollback()
|
||||
@ -89,7 +102,7 @@ void Transaction::rollback()
|
||||
m_cmds->undo();
|
||||
|
||||
delete m_cmds;
|
||||
m_cmds = NULL;
|
||||
m_cmds = nullptr;
|
||||
}
|
||||
|
||||
void Transaction::execute(Cmd* cmd)
|
||||
@ -112,4 +125,9 @@ void Transaction::execute(Cmd* cmd)
|
||||
}
|
||||
}
|
||||
|
||||
void Transaction::onSelectionChanged(DocEvent& ev)
|
||||
{
|
||||
m_changes = Changes(int(m_changes) | int(Changes::kSelection));
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -8,6 +9,8 @@
|
||||
#define APP_TRANSACTION_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/doc_observer.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace app {
|
||||
@ -38,7 +41,7 @@ namespace app {
|
||||
// transaction.commit();
|
||||
// }
|
||||
//
|
||||
class Transaction {
|
||||
class Transaction : public DocObserver {
|
||||
public:
|
||||
// Starts a undoable sequence of operations in a transaction that
|
||||
// can be committed or rollbacked. All the operations will be
|
||||
@ -67,11 +70,20 @@ namespace app {
|
||||
void execute(Cmd* cmd);
|
||||
|
||||
private:
|
||||
// List of changes during the execution of this transaction
|
||||
enum class Changes { kNone = 0,
|
||||
kSelection = 1 };
|
||||
|
||||
void rollback();
|
||||
|
||||
// DocObserver impl
|
||||
void onSelectionChanged(DocEvent& ev) override;
|
||||
|
||||
Context* m_ctx;
|
||||
Doc* m_doc;
|
||||
DocUndo* m_undo;
|
||||
CmdTransaction* m_cmds;
|
||||
Changes m_changes;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -463,7 +464,6 @@ public:
|
||||
}
|
||||
// Selection ink
|
||||
else if (getInk()->isSelection()) {
|
||||
m_document->generateMaskBoundaries();
|
||||
redraw = true;
|
||||
|
||||
// Show selection edges
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -1784,7 +1784,7 @@ void Timeline::onRemoveFrame(DocEvent& ev)
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void Timeline::onSelectionChanged(DocEvent& ev)
|
||||
void Timeline::onSelectionBoundariesChanged(DocEvent& ev)
|
||||
{
|
||||
if (m_rangeLocks == 0)
|
||||
clearAndInvalidateRange();
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -144,7 +144,7 @@ namespace app {
|
||||
void onAfterRemoveLayer(DocEvent& ev) override;
|
||||
void onAddFrame(DocEvent& ev) override;
|
||||
void onRemoveFrame(DocEvent& ev) override;
|
||||
void onSelectionChanged(DocEvent& ev) override;
|
||||
void onSelectionBoundariesChanged(DocEvent& ev) override;
|
||||
void onLayerNameChange(DocEvent& ev) override;
|
||||
void onAddFrameTag(DocEvent& ev) override;
|
||||
void onRemoveFrameTag(DocEvent& ev) override;
|
||||
|
Loading…
x
Reference in New Issue
Block a user