ContextBar: Add buttons to drop the selection or cancel the whole operation

- Add ContextBarObserver (and MovingPixelsState implements this interface)
- PixelMovements::discardImage() receives a "commit" flag to do a rollback
  of the operation if the user needs it.
This commit is contained in:
David Capello 2014-05-26 00:20:16 -03:00
parent b05f2da0b2
commit dc5a019c13
11 changed files with 146 additions and 7 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -323,6 +323,10 @@
<part id="timeline_loop_range" x="240" y="132" w1="3" w2="6" w3="3" h1="3" h2="6" h3="3" />
<part id="flag_normal" x="0" y="240" w="16" h="10" />
<part id="flag_highlight" x="16" y="240" w="16" h="10" />
<part id="drop_pixels_ok" x="176" y="176" w="7" h="8" />
<part id="drop_pixels_ok_selected" x="176" y="184" w="7" h="8" />
<part id="drop_pixels_cancel" x="192" y="176" w="7" h="8" />
<part id="drop_pixels_cancel_selected" x="192" y="184" w="7" h="8" />
</parts>
<stylesheet>

View File

@ -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<void, ContextBarObserver::DropAction> 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

View File

@ -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<ContextBarObserver> {
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

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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).

View File

@ -82,7 +82,7 @@ namespace app {
void dropImageTemporarily();
void dropImage();
void discardImage();
void discardImage(bool commit = true);
bool isDragging() const;
gfx::Rect getImageBounds();

View File

@ -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
};

View File

@ -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;