From 02ad6b9b78377d78b9e43e4157a261d2d800ec3b Mon Sep 17 00:00:00 2001 From: David Capello Date: Sun, 15 Feb 2015 17:08:21 -0300 Subject: [PATCH] Fix several bugs dropping pixels in the invalid editor --- src/app/ui/editor/editor.cpp | 6 ++--- src/app/ui/editor/moving_pixels_state.cpp | 31 ++++++++++++++++------- src/app/ui/editor/moving_pixels_state.h | 4 +-- src/app/ui/editor/pixels_movement.cpp | 18 +++++++------ src/app/ui/editor/pixels_movement.h | 8 +++--- src/app/ui/editor/standby_state.cpp | 6 ++--- src/app/ui/editor/tool_loop_impl.cpp | 3 ++- src/app/util/expand_cel_canvas.cpp | 15 +++++------ src/app/util/expand_cel_canvas.h | 7 ++--- 9 files changed, 57 insertions(+), 41 deletions(-) diff --git a/src/app/ui/editor/editor.cpp b/src/app/ui/editor/editor.cpp index ac68cb371..41816aa06 100644 --- a/src/app/ui/editor/editor.cpp +++ b/src/app/ui/editor/editor.cpp @@ -1395,10 +1395,8 @@ void Editor::pasteImage(const Image* image, int x, int y) ToolBar::instance()->selectTool(defaultSelectionTool); } - Document* document = this->document(); - int opacity = 255; Sprite* sprite = this->sprite(); - Layer* layer = this->layer(); + int opacity = 255; // Check bounds where the image will be pasted. { @@ -1414,7 +1412,7 @@ void Editor::pasteImage(const Image* image, int x, int y) PixelsMovementPtr pixelsMovement( new PixelsMovement(UIContext::instance(), - document, sprite, layer, + getDocumentLocation(), image, x, y, opacity, "Paste")); // Select the pasted image so the user can move it and transform it. diff --git a/src/app/ui/editor/moving_pixels_state.cpp b/src/app/ui/editor/moving_pixels_state.cpp index 584bc4ebe..8b1efdfda 100644 --- a/src/app/ui/editor/moving_pixels_state.cpp +++ b/src/app/ui/editor/moving_pixels_state.cpp @@ -132,6 +132,7 @@ void MovingPixelsState::translate(int dx, int dy) EditorState::BeforeChangeAction MovingPixelsState::onBeforeChangeState(Editor* editor, EditorState* newState) { ASSERT(m_pixelsMovement != NULL); + ASSERT(editor == m_editor); // If we are changing to another state, we've to drop the image. if (m_pixelsMovement->isDragging()) @@ -160,6 +161,7 @@ EditorState::BeforeChangeAction MovingPixelsState::onBeforeChangeState(Editor* e void MovingPixelsState::onCurrentToolChange(Editor* editor) { ASSERT(m_pixelsMovement != NULL); + ASSERT(editor == m_editor); tools::Tool* current_tool = editor->getCurrentEditorTool(); @@ -169,13 +171,14 @@ void MovingPixelsState::onCurrentToolChange(Editor* editor) (!current_tool->getInk(0)->isSelection() || !current_tool->getInk(1)->isSelection())) { // We have to drop pixels - dropPixels(editor); + dropPixels(); } } bool MovingPixelsState::onMouseDown(Editor* editor, MouseMessage* msg) { ASSERT(m_pixelsMovement != NULL); + ASSERT(editor == m_editor); // Set this editor as the active one and setup the ContextBar for // moving pixels. This is needed in case that the user is working @@ -243,7 +246,7 @@ bool MovingPixelsState::onMouseDown(Editor* editor, MouseMessage* msg) // End "moving pixels" loop else { // Drop pixels (e.g. to start drawing) - dropPixels(editor); + dropPixels(); } // Use StandbyState implementation @@ -253,6 +256,7 @@ bool MovingPixelsState::onMouseDown(Editor* editor, MouseMessage* msg) bool MovingPixelsState::onMouseUp(Editor* editor, MouseMessage* msg) { ASSERT(m_pixelsMovement != NULL); + ASSERT(editor == m_editor); // Drop the image temporarily in this location (where the user releases the mouse) m_pixelsMovement->dropImageTemporarily(); @@ -267,6 +271,7 @@ bool MovingPixelsState::onMouseUp(Editor* editor, MouseMessage* msg) bool MovingPixelsState::onMouseMove(Editor* editor, MouseMessage* msg) { ASSERT(m_pixelsMovement != NULL); + ASSERT(editor == m_editor); // If there is a button pressed if (m_pixelsMovement->isDragging()) { @@ -311,6 +316,7 @@ bool MovingPixelsState::onMouseMove(Editor* editor, MouseMessage* msg) bool MovingPixelsState::onSetCursor(Editor* editor) { ASSERT(m_pixelsMovement != NULL); + ASSERT(editor == m_editor); // Move selection if (m_pixelsMovement->isDragging()) { @@ -326,11 +332,14 @@ bool MovingPixelsState::onSetCursor(Editor* editor) bool MovingPixelsState::onKeyDown(Editor* editor, KeyMessage* msg) { ASSERT(m_pixelsMovement != NULL); + if (!isActiveEditor()) + return false; + ASSERT(editor == m_editor); if (msg->scancode() == kKeyEnter || // TODO make this key customizable msg->scancode() == kKeyEnterPad || msg->scancode() == kKeyEsc) { - dropPixels(editor); + dropPixels(); // The escape key drop pixels and deselect the mask. if (msg->scancode() == kKeyEsc) { // TODO make this key customizable @@ -396,6 +405,9 @@ bool MovingPixelsState::onKeyDown(Editor* editor, KeyMessage* msg) bool MovingPixelsState::onKeyUp(Editor* editor, KeyMessage* msg) { ASSERT(m_pixelsMovement != NULL); + if (!isActiveEditor()) + return false; + ASSERT(editor == m_editor); // Use StandbyState implementation return StandbyState::onKeyUp(editor, msg); @@ -404,6 +416,7 @@ bool MovingPixelsState::onKeyUp(Editor* editor, KeyMessage* msg) bool MovingPixelsState::onUpdateStatusBar(Editor* editor) { ASSERT(m_pixelsMovement != NULL); + ASSERT(editor == m_editor); const gfx::Transformation& transform(getTransformation(editor)); gfx::Size imageSize = m_pixelsMovement->getInitialImageSize(); @@ -448,7 +461,7 @@ void MovingPixelsState::onBeforeCommandExecution(Command* command) } if (m_pixelsMovement) - dropPixels(m_editor); + dropPixels(); } void MovingPixelsState::onBeforeFrameChanged(Editor* editor) @@ -457,7 +470,7 @@ void MovingPixelsState::onBeforeFrameChanged(Editor* editor) return; if (m_pixelsMovement) - dropPixels(m_editor); + dropPixels(); } void MovingPixelsState::onBeforeLayerChanged(Editor* editor) @@ -466,7 +479,7 @@ void MovingPixelsState::onBeforeLayerChanged(Editor* editor) return; if (m_pixelsMovement) - dropPixels(m_editor); + dropPixels(); } void MovingPixelsState::onSetMoveTransparentColor(app::Color newColor) @@ -483,7 +496,7 @@ void MovingPixelsState::onDropPixels(ContextBarObserver::DropAction action) switch (action) { case ContextBarObserver::DropPixels: - dropPixels(m_editor); + dropPixels(); break; case ContextBarObserver::CancelDrag: @@ -507,11 +520,11 @@ void MovingPixelsState::setTransparentColor(const app::Color& color) color_utils::color_for_target_mask(color, ColorTarget(layer))); } -void MovingPixelsState::dropPixels(Editor* editor) +void MovingPixelsState::dropPixels() { // Just change to default state (StandbyState generally). We'll // receive an onBeforeChangeState() event after this call. - editor->backToPreviousState(); + m_editor->backToPreviousState(); } gfx::Transformation MovingPixelsState::getTransformation(Editor* editor) diff --git a/src/app/ui/editor/moving_pixels_state.h b/src/app/ui/editor/moving_pixels_state.h index 60597be1d..5fd3f29c6 100644 --- a/src/app/ui/editor/moving_pixels_state.h +++ b/src/app/ui/editor/moving_pixels_state.h @@ -1,5 +1,5 @@ /* Aseprite - * Copyright (C) 2001-2013 David Capello + * Copyright (C) 2001-2015 David Capello * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -78,7 +78,7 @@ namespace app { void onBeforeCommandExecution(Command* command); void setTransparentColor(const app::Color& color); - void dropPixels(Editor* editor); + void dropPixels(); bool isActiveDocument() const; bool isActiveEditor() const; diff --git a/src/app/ui/editor/pixels_movement.cpp b/src/app/ui/editor/pixels_movement.cpp index c9e16ef43..5fd0a255a 100644 --- a/src/app/ui/editor/pixels_movement.cpp +++ b/src/app/ui/editor/pixels_movement.cpp @@ -1,5 +1,5 @@ /* Aseprite - * Copyright (C) 2001-2014 David Capello + * Copyright (C) 2001-2015 David Capello * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,12 +47,14 @@ static inline const base::Vector2d point2Vector(const gfx::PointT& pt } PixelsMovement::PixelsMovement(Context* context, - Document* document, Sprite* sprite, Layer* layer, - const Image* moveThis, int initialX, int initialY, int opacity, - const char* operationName) + DocumentLocation location, + const Image* moveThis, int initialX, int initialY, int opacity, + const char* operationName) : m_reader(context) - , m_document(document) - , m_sprite(sprite) + , m_location(location) + , m_document(location.document()) + , m_sprite(location.sprite()) + , m_layer(location.layer()) , m_undoTransaction(context, operationName) , m_firstDrop(true) , m_isDragging(false) @@ -451,8 +453,8 @@ void PixelsMovement::stampImage() { // Expand the canvas to paste the image in the fully visible // portion of sprite. - ExpandCelCanvas expandCelCanvas(writer.context(), TILED_NONE, - m_undoTransaction); + ExpandCelCanvas expandCelCanvas(m_location, + TILED_NONE, m_undoTransaction); composite_image(expandCelCanvas.getDestCanvas(), image, -expandCelCanvas.getCel()->x(), diff --git a/src/app/ui/editor/pixels_movement.h b/src/app/ui/editor/pixels_movement.h index d82e6e01e..34bdc2622 100644 --- a/src/app/ui/editor/pixels_movement.h +++ b/src/app/ui/editor/pixels_movement.h @@ -1,5 +1,5 @@ /* Aseprite - * Copyright (C) 2001-2014 David Capello + * Copyright (C) 2001-2015 David Capello * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -54,7 +54,7 @@ namespace app { // The "moveThis" image specifies the chunk of pixels to be moved. // The "x" and "y" parameters specify the initial position of the image. PixelsMovement(Context* context, - Document* document, Sprite* sprite, Layer* layer, + DocumentLocation location, const Image* moveThis, int x, int y, int opacity, const char* operationName); ~PixelsMovement(); @@ -110,8 +110,10 @@ namespace app { void updateDocumentMask(); const ContextReader m_reader; + DocumentLocation m_location; Document* m_document; Sprite* m_sprite; + Layer* m_layer; UndoTransaction m_undoTransaction; bool m_firstDrop; bool m_isDragging; @@ -133,7 +135,7 @@ namespace app { } typedef SharedPtr PixelsMovementPtr; - + } // namespace app #endif diff --git a/src/app/ui/editor/standby_state.cpp b/src/app/ui/editor/standby_state.cpp index 205de71c7..df407fa02 100644 --- a/src/app/ui/editor/standby_state.cpp +++ b/src/app/ui/editor/standby_state.cpp @@ -1,5 +1,5 @@ /* Aseprite - * Copyright (C) 2001-2013 David Capello + * Copyright (C) 2001-2015 David Capello * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -521,7 +521,7 @@ bool StandbyState::onUpdateStatusBar(Editor* editor) } else { Mask* mask = - (editor->document()->isMaskVisible() ? + (editor->document()->isMaskVisible() ? editor->document()->mask(): NULL); StatusBar::instance()->setStatusText(0, @@ -562,7 +562,7 @@ void StandbyState::transformSelection(Editor* editor, MouseMessage* msg, HandleT Layer* layer = editor->layer(); PixelsMovementPtr pixelsMovement( new PixelsMovement(UIContext::instance(), - document, sprite, layer, + editor->getDocumentLocation(), tmpImage, x, y, opacity, "Transformation")); diff --git a/src/app/ui/editor/tool_loop_impl.cpp b/src/app/ui/editor/tool_loop_impl.cpp index c8852570a..45f5981c6 100644 --- a/src/app/ui/editor/tool_loop_impl.cpp +++ b/src/app/ui/editor/tool_loop_impl.cpp @@ -121,7 +121,8 @@ public: getInk()->isSlice() || getInk()->isZoom()) ? undo::DoesntModifyDocument: undo::ModifyDocument)) - , m_expandCelCanvas(m_context, m_docSettings->getTiledMode(), m_undoTransaction) + , m_expandCelCanvas(editor->getDocumentLocation(), + m_docSettings->getTiledMode(), m_undoTransaction) , m_shadeTable(NULL) { // Settings diff --git a/src/app/util/expand_cel_canvas.cpp b/src/app/util/expand_cel_canvas.cpp index 4199b4ae0..09bbe7609 100644 --- a/src/app/util/expand_cel_canvas.cpp +++ b/src/app/util/expand_cel_canvas.cpp @@ -1,5 +1,5 @@ /* Aseprite - * Copyright (C) 2001-2013 David Capello + * Copyright (C) 2001-2015 David Capello * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -65,8 +65,12 @@ static void create_buffers() namespace app { -ExpandCelCanvas::ExpandCelCanvas(Context* context, TiledMode tiledMode, UndoTransaction& undo) - : m_cel(NULL) +ExpandCelCanvas::ExpandCelCanvas(DocumentLocation location, + TiledMode tiledMode, UndoTransaction& undo) + : m_document(location.document()) + , m_sprite(location.sprite()) + , m_layer(location.layer()) + , m_cel(NULL) , m_celImage(NULL) , m_celCreated(false) , m_closed(false) @@ -75,11 +79,6 @@ ExpandCelCanvas::ExpandCelCanvas(Context* context, TiledMode tiledMode, UndoTran { create_buffers(); - DocumentLocation location = context->activeLocation(); - m_document = location.document(); - m_sprite = location.sprite(); - m_layer = location.layer(); - if (m_layer->isImage()) { m_cel = static_cast(m_layer)->getCel(location.frame()); if (m_cel) diff --git a/src/app/util/expand_cel_canvas.h b/src/app/util/expand_cel_canvas.h index bb4bf9338..30a76565d 100644 --- a/src/app/util/expand_cel_canvas.h +++ b/src/app/util/expand_cel_canvas.h @@ -1,5 +1,5 @@ /* Aseprite - * Copyright (C) 2001-2013 David Capello + * Copyright (C) 2001-2015 David Capello * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,8 +31,8 @@ namespace raster { } namespace app { - class Context; class Document; + class DocumentLocation; class UndoTransaction; using namespace filters; @@ -46,7 +46,8 @@ namespace app { // state using "Undo" command. class ExpandCelCanvas { public: - ExpandCelCanvas(Context* context, TiledMode tiledMode, UndoTransaction& undo); + ExpandCelCanvas(DocumentLocation location, + TiledMode tiledMode, UndoTransaction& undo); ~ExpandCelCanvas(); // Commit changes made in getDestCanvas() in the cel's image. Adds