From 0d582f9d5fb059f54e489e9d7a162aaa29bd52e7 Mon Sep 17 00:00:00 2001 From: David Capello Date: Mon, 6 Feb 2012 00:17:42 -0300 Subject: [PATCH] Improve the MovingPixelsState to support Enter and Esc keys to drop the pixels. Also any executed command will drop the pixels and return the editor to its standby state. --- data/gui.xml | 1 + src/CMakeLists.txt | 1 + src/commands/cmd_cancel.cpp | 60 ++++++++++++++++++++++ src/commands/commands_list.h | 1 + src/widgets/editor/moving_pixels_state.cpp | 54 ++++++++++++++++--- src/widgets/editor/moving_pixels_state.h | 8 ++- src/widgets/editor/pixels_movement.cpp | 49 ++++++++++-------- src/widgets/editor/pixels_movement.h | 3 ++ 8 files changed, 148 insertions(+), 29 deletions(-) create mode 100644 src/commands/cmd_cancel.cpp diff --git a/data/gui.xml b/data/gui.xml index f6e623281..a5ea88618 100644 --- a/data/gui.xml +++ b/data/gui.xml @@ -18,6 +18,7 @@ + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b69a70855..7a2aae48e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -122,6 +122,7 @@ add_library(aseprite-library commands/cmd_about.cpp commands/cmd_advanced_mode.cpp commands/cmd_background_from_layer.cpp + commands/cmd_cancel.cpp commands/cmd_canvas_size.cpp commands/cmd_cel_properties.cpp commands/cmd_change_color.cpp diff --git a/src/commands/cmd_cancel.cpp b/src/commands/cmd_cancel.cpp new file mode 100644 index 000000000..c9b7c5c02 --- /dev/null +++ b/src/commands/cmd_cancel.cpp @@ -0,0 +1,60 @@ +/* ASEPRITE + * Copyright (C) 2001-2012 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include "commands/command.h" + +#include "commands/commands.h" +#include "context.h" +#include "document.h" +#include "document_wrappers.h" + +class CancelCommand : public Command +{ +public: + CancelCommand(); + Command* clone() { return new CancelCommand(*this); } + +protected: + void onExecute(Context* context); +}; + +CancelCommand::CancelCommand() + : Command("Cancel", + "Cancel", + CmdUIOnlyFlag) +{ +} + +void CancelCommand::onExecute(Context* context) +{ + if (context->checkFlags(ContextFlags::ActiveDocumentIsWritable | + ContextFlags::HasVisibleMask)) { + Command* cmd = CommandsModule::instance()->getCommandByName(CommandId::DeselectMask); + context->executeCommand(cmd); + } +} + +////////////////////////////////////////////////////////////////////// +// CommandFactory + +Command* CommandFactory::createCancelCommand() +{ + return new CancelCommand; +} diff --git a/src/commands/commands_list.h b/src/commands/commands_list.h index 60c4b8aa9..9b5099252 100644 --- a/src/commands/commands_list.h +++ b/src/commands/commands_list.h @@ -20,6 +20,7 @@ FOR_EACH_COMMAND(About) FOR_EACH_COMMAND(AdvancedMode) FOR_EACH_COMMAND(AutocropSprite) FOR_EACH_COMMAND(BackgroundFromLayer) +FOR_EACH_COMMAND(Cancel) FOR_EACH_COMMAND(CanvasSize) FOR_EACH_COMMAND(CelProperties) FOR_EACH_COMMAND(ChangeColor) diff --git a/src/widgets/editor/moving_pixels_state.cpp b/src/widgets/editor/moving_pixels_state.cpp index 247704cd2..172d3a4fd 100644 --- a/src/widgets/editor/moving_pixels_state.cpp +++ b/src/widgets/editor/moving_pixels_state.cpp @@ -23,7 +23,9 @@ #include "app.h" #include "app/color_utils.h" #include "base/unique_ptr.h" +#include "commands/commands.h" #include "gfx/rect.h" +#include "gui/manager.h" #include "gui/message.h" #include "gui/system.h" #include "gui/view.h" @@ -32,6 +34,7 @@ #include "raster/sprite.h" #include "tools/ink.h" #include "tools/tool.h" +#include "ui_context.h" #include "widgets/editor/editor.h" #include "widgets/editor/editor_customization_delegate.h" #include "widgets/editor/pixels_movement.h" @@ -42,6 +45,7 @@ #include MovingPixelsState::MovingPixelsState(Editor* editor, Message* msg, PixelsMovement* pixelsMovement, HandleType handle) + : m_currentEditor(editor) { // MovingPixelsState needs a selection tool to avoid problems // sharing the extra cel between the drawing cursor preview and the @@ -62,15 +66,34 @@ MovingPixelsState::MovingPixelsState(Editor* editor, Message* msg, PixelsMovemen // Setup mask color setTransparentColor(app_get_statusbar()->getTransparentColor()); + // Add this class as: + // - listener of the UI context: so we know if the user wants to execute + // other command, so we can drop pixels. + // - listener of the status bar to know if the user has changed the + // transparent color. + UIContext::instance()->addListener(this); app_get_statusbar()->addListener(this); + + // Show controls to modify the "pixels movement" options (e.g. the + // transparent color). app_get_statusbar()->showMovePixelsOptions(); + + // Add the current editor as filter for key message of the manager + // so we can catch the Enter key, and avoid to execute the + // PlayAnimation command. + jmanager_add_msg_filter(JM_KEYPRESSED, m_currentEditor); + jmanager_add_msg_filter(JM_KEYRELEASED, m_currentEditor); } MovingPixelsState::~MovingPixelsState() { + UIContext::instance()->removeListener(this); app_get_statusbar()->removeListener(this); delete m_pixelsMovement; + + jmanager_remove_msg_filter(JM_KEYPRESSED, m_currentEditor); + jmanager_remove_msg_filter(JM_KEYRELEASED, m_currentEditor); } EditorState::BeforeChangeAction MovingPixelsState::onBeforeChangeState(Editor* editor, EditorState* newState) @@ -153,6 +176,13 @@ bool MovingPixelsState::onMouseDown(Editor* editor, Message* msg) // Start "moving pixels" loop if (editor->isInsideSelection() && (msg->mouse.left || msg->mouse.right)) { + // In case that the user is pressing the copy-selection keyboard shortcut. + EditorCustomizationDelegate* customization = editor->getCustomizationDelegate(); + if (customization && customization->isCopySelectionKeyPressed()) { + // Stamp the pixels to create the copy. + m_pixelsMovement->stampImage(); + } + // Re-catch the image int x, y; editor->screenToEditor(msg->mouse.x, msg->mouse.y, &x, &y); @@ -257,15 +287,16 @@ bool MovingPixelsState::onSetCursor(Editor* editor) bool MovingPixelsState::onKeyDown(Editor* editor, Message* msg) { ASSERT(m_pixelsMovement != NULL); - EditorCustomizationDelegate* customization = editor->getCustomizationDelegate(); - if (customization && customization->isCopySelectionKeyPressed()) { - // If the user presses the CTRL key when he is dragging pixels (but - // not pressing the mouse buttons). - if (!jmouse_b(0) && m_pixelsMovement) { - // Drop pixels (sure the user will press the mouse button to - // start dragging a copy). - dropPixels(editor); + if (msg->key.scancode == KEY_ENTER || // TODO make this key customizable + msg->key.scancode == KEY_ENTER_PAD || + msg->key.scancode == KEY_ESC) { + dropPixels(editor); + + // The escape key drop pixels and deselect the mask. + if (msg->key.scancode == KEY_ESC) { // TODO make this key customizable + Command* cmd = CommandsModule::instance()->getCommandByName(CommandId::DeselectMask); + UIContext::instance()->executeCommand(cmd); } } @@ -301,6 +332,13 @@ bool MovingPixelsState::onUpdateStatusBar(Editor* editor) return true; } +// Before executing any command, we drop the pixels (go back to standby). +void MovingPixelsState::onCommandBeforeExecution(Context* context) +{ + if (m_pixelsMovement) + dropPixels(m_currentEditor); +} + void MovingPixelsState::dispose() { // Never called as MovingPixelsState is removed automatically as diff --git a/src/widgets/editor/moving_pixels_state.h b/src/widgets/editor/moving_pixels_state.h index b078b6806..723a6446e 100644 --- a/src/widgets/editor/moving_pixels_state.h +++ b/src/widgets/editor/moving_pixels_state.h @@ -20,6 +20,7 @@ #define WIDGETS_EDITOR_MOVING_PIXELS_STATE_H_INCLUDED #include "base/compiler_specific.h" +#include "context_listener.h" #include "widgets/editor/handle_type.h" #include "widgets/editor/standby_state.h" #include "widgets/statebar.h" @@ -28,12 +29,13 @@ class Editor; class Image; class PixelsMovement; -class MovingPixelsState : public StandbyState, StatusBarListener +class MovingPixelsState : public StandbyState, StatusBarListener, ContextListener { public: MovingPixelsState(Editor* editor, Message* msg, PixelsMovement* pixelsMovement, HandleType handle); virtual ~MovingPixelsState(); + // EditorState virtual BeforeChangeAction onBeforeChangeState(Editor* editor, EditorState* newState) OVERRIDE; virtual void onCurrentToolChange(Editor* editor) OVERRIDE; virtual bool onMouseDown(Editor* editor, Message* msg) OVERRIDE; @@ -45,6 +47,9 @@ public: virtual bool onKeyUp(Editor* editor, Message* msg) OVERRIDE; virtual bool onUpdateStatusBar(Editor* editor) OVERRIDE; + // ContextListener + virtual void onCommandBeforeExecution(Context* context) OVERRIDE; + virtual gfx::Transformation getTransformation(Editor* editor) OVERRIDE; protected: @@ -58,6 +63,7 @@ private: // Helper member to move/translate selection and pixels. PixelsMovement* m_pixelsMovement; + Editor* m_currentEditor; }; #endif // WIDGETS_EDITOR_MOVING_PIXELS_STATE_H_INCLUDED diff --git a/src/widgets/editor/pixels_movement.cpp b/src/widgets/editor/pixels_movement.cpp index 59a34bed8..c2fe54163 100644 --- a/src/widgets/editor/pixels_movement.cpp +++ b/src/widgets/editor/pixels_movement.cpp @@ -350,6 +350,31 @@ gfx::Rect PixelsMovement::moveImage(int x, int y, MoveModifier moveModifier) return gfx::Rect(0, 0, m_sprite->getWidth(), m_sprite->getHeight()); } +void PixelsMovement::stampImage() +{ + const Cel* cel = m_documentReader->getExtraCel(); + const Image* image = m_documentReader->getExtraCelImage(); + + { + DocumentWriter documentWriter(m_documentReader); + { + // Expand the canvas to paste the image in the fully visible + // portion of sprite. + ExpandCelCanvas expandCelCanvas(documentWriter, m_sprite, + m_sprite->getCurrentLayer(), TILED_NONE); + + image_merge(expandCelCanvas.getDestCanvas(), image, + -expandCelCanvas.getCel()->getX(), + -expandCelCanvas.getCel()->getY(), + cel->getOpacity(), BLEND_MODE_NORMAL); + + expandCelCanvas.commit(); + } + // TODO + // m_undoTransaction.commit(); + } +} + void PixelsMovement::dropImageTemporarily() { m_isDragging = false; @@ -395,28 +420,12 @@ void PixelsMovement::dropImage() { m_isDragging = false; - const Cel* cel = m_documentReader->getExtraCel(); - const Image* image = m_documentReader->getExtraCelImage(); + stampImage(); - { - DocumentWriter documentWriter(m_documentReader); - { - // Expand the canvas to paste the image in the fully visible - // portion of sprite. - ExpandCelCanvas expandCelCanvas(documentWriter, m_sprite, - m_sprite->getCurrentLayer(), TILED_NONE); + m_undoTransaction.commit(); - image_merge(expandCelCanvas.getDestCanvas(), image, - -expandCelCanvas.getCel()->getX(), - -expandCelCanvas.getCel()->getY(), - cel->getOpacity(), BLEND_MODE_NORMAL); - - expandCelCanvas.commit(); - } - m_undoTransaction.commit(); - - documentWriter->destroyExtraCel(); - } + DocumentWriter documentWriter(m_documentReader); + documentWriter->destroyExtraCel(); } bool PixelsMovement::isDragging() const diff --git a/src/widgets/editor/pixels_movement.h b/src/widgets/editor/pixels_movement.h index 9d311c947..9bc5d412b 100644 --- a/src/widgets/editor/pixels_movement.h +++ b/src/widgets/editor/pixels_movement.h @@ -63,6 +63,9 @@ public: // redrawn. gfx::Rect moveImage(int x, int y, MoveModifier moveModifier); + // Copies the image being dragged in the current position. + void stampImage(); + void dropImageTemporarily(); void dropImage(); bool isDragging() const;