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;