diff --git a/data/skins/default/sheet.png b/data/skins/default/sheet.png index 8d1c00094..1fdd2bdfa 100644 Binary files a/data/skins/default/sheet.png and b/data/skins/default/sheet.png differ diff --git a/data/skins/default/skin.xml b/data/skins/default/skin.xml index 44c2edfc3..ae2ec5c6c 100644 --- a/data/skins/default/skin.xml +++ b/data/skins/default/skin.xml @@ -323,6 +323,10 @@ + + + + diff --git a/src/app/ui/context_bar.cpp b/src/app/ui/context_bar.cpp index c45d93b9f..ca84b0f59 100644 --- a/src/app/ui/context_bar.cpp +++ b/src/app/ui/context_bar.cpp @@ -476,6 +476,32 @@ protected: } }; +class ContextBar::DropPixelsField : public ButtonSet +{ +public: + DropPixelsField() : ButtonSet(2, 1, -1, + PART_DROP_PIXELS_OK, + PART_DROP_PIXELS_CANCEL) { + } + + void setupTooltips(TooltipManager* tooltipManager) { + tooltipManager->addTooltipFor(getButtonAt(0), "Drop pixels here", JI_BOTTOM); + tooltipManager->addTooltipFor(getButtonAt(1), "Cancel drag and drop", JI_BOTTOM); + } + + Signal1 DropPixels; + +protected: + void onItemChange() OVERRIDE { + ButtonSet::onItemChange(); + + switch (getSelectedItem()) { + case 0: DropPixels(ContextBarObserver::DropPixels); break; + case 1: DropPixels(ContextBarObserver::CancelDrag); break; + } + } +}; + class ContextBar::GrabAlphaField : public CheckBox { public: @@ -503,6 +529,7 @@ ContextBar::ContextBar() setBgColor(theme->getColor(ThemeColor::Workspace)); addChild(m_selectionOptionsBox = new HBox()); + m_selectionOptionsBox->addChild(m_dropPixels = new DropPixelsField()); m_selectionOptionsBox->addChild(m_selectionMode = new SelectionModeField); m_selectionOptionsBox->addChild(m_transparentColor = new TransparentColorField); m_selectionOptionsBox->addChild(m_rotAlgo = new RotAlgorithmField()); @@ -554,10 +581,12 @@ ContextBar::ContextBar() "When unchecked -the default behavior- the color is picked\n" "from the composition of all sprite layers.", JI_LEFT | JI_TOP); m_selectionMode->setupTooltips(tooltipManager); + m_dropPixels->setupTooltips(tooltipManager); App::instance()->PenSizeAfterChange.connect(&ContextBar::onPenSizeChange, this); App::instance()->PenAngleAfterChange.connect(&ContextBar::onPenAngleChange, this); App::instance()->CurrentToolChange.connect(&ContextBar::onCurrentToolChange, this); + m_dropPixels->DropPixels.connect(&ContextBar::onDropPixels, this); onCurrentToolChange(); } @@ -611,6 +640,11 @@ void ContextBar::onCurrentToolChange() updateFromTool(settings->getCurrentTool()); } +void ContextBar::onDropPixels(ContextBarObserver::DropAction action) +{ + notifyObservers(&ContextBarObserver::onDropPixels, action); +} + void ContextBar::updateFromTool(tools::Tool* tool) { ISettings* settings = UIContext::instance()->getSettings(); @@ -680,8 +714,23 @@ void ContextBar::updateFromTool(tools::Tool* tool) m_tolerance->setVisible(hasTolerance); m_sprayBox->setVisible(hasSprayOptions); m_selectionOptionsBox->setVisible(hasSelectOptions); + m_selectionMode->setVisible(true); + m_dropPixels->setVisible(false); layout(); } +void ContextBar::updateForMovingPixels() +{ + tools::Tool* tool = App::instance()->getToolBox()->getToolById( + tools::WellKnownTools::RectangularMarquee); + if (tool) + updateFromTool(tool); + + m_dropPixels->deselectItems(); + m_dropPixels->setVisible(true); + m_selectionMode->setVisible(false); + layout(); +} + } // namespace app diff --git a/src/app/ui/context_bar.h b/src/app/ui/context_bar.h index b0596b318..aea1b19e3 100644 --- a/src/app/ui/context_bar.h +++ b/src/app/ui/context_bar.h @@ -21,7 +21,9 @@ #pragma once #include "app/settings/settings_observers.h" +#include "app/ui/context_bar_observer.h" #include "base/compiler_specific.h" +#include "base/observable.h" #include "ui/box.h" namespace ui { @@ -38,12 +40,14 @@ namespace app { class IToolSettings; class ContextBar : public ui::Box, - public ToolSettingsObserver { + public ToolSettingsObserver, + public base::Observable { public: ContextBar(); ~ContextBar(); void updateFromTool(tools::Tool* tool); + void updateForMovingPixels(); protected: bool onProcessMessage(ui::Message* msg) OVERRIDE; @@ -56,6 +60,7 @@ namespace app { void onPenSizeChange(); void onPenAngleChange(); void onCurrentToolChange(); + void onDropPixels(ContextBarObserver::DropAction action); class BrushTypeField; class BrushAngleField; @@ -70,6 +75,7 @@ namespace app { class RotAlgorithmField; class FreehandAlgorithmField; class GrabAlphaField; + class DropPixelsField; IToolSettings* m_toolSettings; BrushTypeField* m_brushType; @@ -90,6 +96,7 @@ namespace app { SelectionModeField* m_selectionMode; TransparentColorField* m_transparentColor; RotAlgorithmField* m_rotAlgo; + DropPixelsField* m_dropPixels; }; } // namespace app diff --git a/src/app/ui/context_bar_observer.h b/src/app/ui/context_bar_observer.h new file mode 100644 index 000000000..2d0849f02 --- /dev/null +++ b/src/app/ui/context_bar_observer.h @@ -0,0 +1,35 @@ +/* Aseprite + * Copyright (C) 2001-2014 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 + */ + +#ifndef APP_CONTEXT_BAR_OBSERVER_H_INCLUDED +#define APP_CONTEXT_BAR_OBSERVER_H_INCLUDED +#pragma once + +namespace app { + +class ContextBarObserver { +public: + enum DropAction { DropPixels, CancelDrag }; + + virtual ~ContextBarObserver() { } + virtual void onDropPixels(DropAction action) { } +}; + +} // namespace app + +#endif diff --git a/src/app/ui/editor/moving_pixels_state.cpp b/src/app/ui/editor/moving_pixels_state.cpp index d6bab0d31..5c57a8898 100644 --- a/src/app/ui/editor/moving_pixels_state.cpp +++ b/src/app/ui/editor/moving_pixels_state.cpp @@ -31,11 +31,13 @@ #include "app/settings/settings.h" #include "app/tools/ink.h" #include "app/tools/tool.h" +#include "app/ui/context_bar.h" #include "app/ui/editor/editor.h" #include "app/ui/editor/editor_customization_delegate.h" #include "app/ui/editor/pixels_movement.h" #include "app/ui/editor/standby_state.h" #include "app/ui/editor/transform_handles.h" +#include "app/ui/main_window.h" #include "app/ui/status_bar.h" #include "app/ui_context.h" #include "app/util/clipboard.h" @@ -93,10 +95,18 @@ MovingPixelsState::MovingPixelsState(Editor* editor, MouseMessage* msg, PixelsMo // PlayAnimation command. m_currentEditor->getManager()->addMessageFilter(kKeyDownMessage, m_currentEditor); m_currentEditor->getManager()->addMessageFilter(kKeyUpMessage, m_currentEditor); + + ContextBar* contextBar = App::instance()->getMainWindow()->getContextBar(); + contextBar->updateForMovingPixels(); + contextBar->addObserver(this); } MovingPixelsState::~MovingPixelsState() { + ContextBar* contextBar = App::instance()->getMainWindow()->getContextBar(); + contextBar->removeObserver(this); + contextBar->updateFromTool(UIContext::instance()->settings()->getCurrentTool()); + UIContext::instance()->removeObserver(this); UIContext::instance()->settings()->selection()->removeObserver(this); @@ -104,6 +114,8 @@ MovingPixelsState::~MovingPixelsState() m_currentEditor->getManager()->removeMessageFilter(kKeyDownMessage, m_currentEditor); m_currentEditor->getManager()->removeMessageFilter(kKeyUpMessage, m_currentEditor); + + m_currentEditor->getDocument()->generateMaskBoundaries(); } EditorState::BeforeChangeAction MovingPixelsState::onBeforeChangeState(Editor* editor, EditorState* newState) @@ -388,6 +400,24 @@ void MovingPixelsState::onSetMoveTransparentColor(app::Color newColor) setTransparentColor(color); } +void MovingPixelsState::onDropPixels(ContextBarObserver::DropAction action) +{ + switch (action) { + + case ContextBarObserver::DropPixels: + dropPixels(m_currentEditor); + break; + + case ContextBarObserver::CancelDrag: + m_pixelsMovement->discardImage(false); + m_discarded = true; + + // Quit from MovingPixelsState, back to standby. + m_currentEditor->backToPreviousState(); + break; + } +} + void MovingPixelsState::setTransparentColor(const app::Color& color) { ASSERT(m_pixelsMovement != NULL); diff --git a/src/app/ui/editor/moving_pixels_state.h b/src/app/ui/editor/moving_pixels_state.h index a57a61ef1..2058dca4d 100644 --- a/src/app/ui/editor/moving_pixels_state.h +++ b/src/app/ui/editor/moving_pixels_state.h @@ -22,7 +22,7 @@ #include "app/context_observer.h" #include "app/settings/settings_observers.h" -#include "app/ui/context_bar.h" +#include "app/ui/context_bar_observer.h" #include "app/ui/editor/handle_type.h" #include "app/ui/editor/pixels_movement.h" #include "app/ui/editor/standby_state.h" @@ -39,7 +39,8 @@ namespace app { class MovingPixelsState : public StandbyState , ContextObserver - , SelectionSettingsObserver { + , SelectionSettingsObserver + , ContextBarObserver { public: MovingPixelsState(Editor* editor, ui::MouseMessage* msg, PixelsMovementPtr pixelsMovement, HandleType handle); virtual ~MovingPixelsState(); @@ -61,8 +62,10 @@ namespace app { // SettingsObserver virtual void onSetMoveTransparentColor(app::Color newColor) OVERRIDE; - virtual gfx::Transformation getTransformation(Editor* editor) OVERRIDE; + // ContextBarObserver + virtual void onDropPixels(ContextBarObserver::DropAction action) OVERRIDE; + virtual gfx::Transformation getTransformation(Editor* editor) OVERRIDE; private: void setTransparentColor(const app::Color& color); diff --git a/src/app/ui/editor/pixels_movement.cpp b/src/app/ui/editor/pixels_movement.cpp index cedce15e1..ba98f2d08 100644 --- a/src/app/ui/editor/pixels_movement.cpp +++ b/src/app/ui/editor/pixels_movement.cpp @@ -530,13 +530,15 @@ void PixelsMovement::dropImage() m_document->destroyExtraCel(); } -void PixelsMovement::discardImage() +void PixelsMovement::discardImage(bool commit) { m_isDragging = false; // Deselect the mask (here we don't stamp the image). m_document->getApi().deselectMask(); - m_undoTransaction.commit(); + + if (commit) + m_undoTransaction.commit(); // Destroy the extra cel and regenerate the mask boundaries (we've // just deselect the mask). diff --git a/src/app/ui/editor/pixels_movement.h b/src/app/ui/editor/pixels_movement.h index 56a43cf4d..1d656a43d 100644 --- a/src/app/ui/editor/pixels_movement.h +++ b/src/app/ui/editor/pixels_movement.h @@ -82,7 +82,7 @@ namespace app { void dropImageTemporarily(); void dropImage(); - void discardImage(); + void discardImage(bool commit = true); bool isDragging() const; gfx::Rect getImageBounds(); diff --git a/src/app/ui/skin/skin_parts.h b/src/app/ui/skin/skin_parts.h index d2442a68a..3d8ebf283 100644 --- a/src/app/ui/skin/skin_parts.h +++ b/src/app/ui/skin/skin_parts.h @@ -195,6 +195,11 @@ namespace app { PART_TRANSFORMATION_HANDLE, PART_PIVOT_HANDLE, + PART_DROP_PIXELS_OK, + PART_DROP_PIXELS_OK_SELECTED, + PART_DROP_PIXELS_CANCEL, + PART_DROP_PIXELS_CANCEL_SELECTED, + PARTS }; diff --git a/src/app/ui/skin/skin_theme.cpp b/src/app/ui/skin/skin_theme.cpp index 49ad1226d..30a0fd98e 100644 --- a/src/app/ui/skin/skin_theme.cpp +++ b/src/app/ui/skin/skin_theme.cpp @@ -283,6 +283,10 @@ SkinTheme::SkinTheme() sheet_mapping["drop_down_button_right_selected"] = PART_DROP_DOWN_BUTTON_RIGHT_SELECTED_NW; sheet_mapping["transformation_handle"] = PART_TRANSFORMATION_HANDLE; sheet_mapping["pivot_handle"] = PART_PIVOT_HANDLE; + sheet_mapping["drop_pixels_ok"] = PART_DROP_PIXELS_OK; + sheet_mapping["drop_pixels_ok_selected"] = PART_DROP_PIXELS_OK_SELECTED; + sheet_mapping["drop_pixels_cancel"] = PART_DROP_PIXELS_CANCEL; + sheet_mapping["drop_pixels_cancel_selected"] = PART_DROP_PIXELS_CANCEL_SELECTED; color_mapping["text"] = ThemeColor::Text; color_mapping["disabled"] = ThemeColor::Disabled;