diff --git a/data/gui.xml b/data/gui.xml
index a1823832a..1d1cb016b 100644
--- a/data/gui.xml
+++ b/data/gui.xml
@@ -483,6 +483,13 @@
+
+
+
+
+
+
+
diff --git a/data/pref.xml b/data/pref.xml
index 656de3a49..299b18e85 100644
--- a/data/pref.xml
+++ b/data/pref.xml
@@ -52,6 +52,11 @@
+
+
+
+!
+
@@ -151,7 +156,7 @@
-
+
diff --git a/src/app/commands/cmd_keyboard_shortcuts.cpp b/src/app/commands/cmd_keyboard_shortcuts.cpp
index acd25cd79..4c1294363 100644
--- a/src/app/commands/cmd_keyboard_shortcuts.cpp
+++ b/src/app/commands/cmd_keyboard_shortcuts.cpp
@@ -1,5 +1,5 @@
// Aseprite
-// Copyright (C) 2001-2015 David Capello
+// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@@ -361,6 +361,9 @@ private:
case KeyContext::FreehandTool:
text = "Freehand Tools: " + text;
break;
+ case KeyContext::ShapeTool:
+ text = "Shape Tools: " + text;
+ break;
}
KeyItem* keyItem = new KeyItem(text, key, NULL, 0);
diff --git a/src/app/commands/cmd_select_tile.cpp b/src/app/commands/cmd_select_tile.cpp
index 0de6d17a5..8569b1578 100644
--- a/src/app/commands/cmd_select_tile.cpp
+++ b/src/app/commands/cmd_select_tile.cpp
@@ -38,14 +38,14 @@ protected:
std::string onGetFriendlyName() const override;
private:
- tools::SelectionMode m_mode;
+ gen::SelectionMode m_mode;
};
SelectTileCommand::SelectTileCommand()
: Command("SelectTile",
"Select Tile",
CmdRecordableFlag)
- , m_mode(tools::SelectionMode::DEFAULT)
+ , m_mode(gen::SelectionMode::DEFAULT)
{
}
@@ -53,11 +53,11 @@ void SelectTileCommand::onLoadParams(const Params& params)
{
std::string mode = params.get("mode");
if (mode == "add")
- m_mode = tools::SelectionMode::ADD;
+ m_mode = gen::SelectionMode::ADD;
else if (mode == "subtract")
- m_mode = tools::SelectionMode::SUBTRACT;
+ m_mode = gen::SelectionMode::SUBTRACT;
else
- m_mode = tools::SelectionMode::DEFAULT;
+ m_mode = gen::SelectionMode::DEFAULT;
}
bool SelectTileCommand::onEnabled(Context* ctx)
@@ -78,7 +78,7 @@ void SelectTileCommand::onExecute(Context* ctx)
base::UniquePtr mask(new Mask());
- if (m_mode != tools::SelectionMode::DEFAULT)
+ if (m_mode != gen::SelectionMode::DEFAULT)
mask->copyFrom(doc->mask());
{
@@ -87,7 +87,7 @@ void SelectTileCommand::onExecute(Context* ctx)
pos = snap_to_grid(gridBounds, pos, PreferSnapTo::BoxOrigin);
gridBounds.setOrigin(pos);
- if (m_mode != tools::SelectionMode::SUBTRACT)
+ if (m_mode != gen::SelectionMode::SUBTRACT)
mask->add(gridBounds);
else
mask->subtract(gridBounds);
@@ -109,8 +109,8 @@ std::string SelectTileCommand::onGetFriendlyName() const
std::string text = "Select Tile";
switch (m_mode) {
- case tools::SelectionMode::ADD: text += " (Add)"; break;
- case tools::SelectionMode::SUBTRACT: text += " (Subtract)"; break;
+ case gen::SelectionMode::ADD: text += " (Add)"; break;
+ case gen::SelectionMode::SUBTRACT: text += " (Subtract)"; break;
}
return text;
diff --git a/src/app/pref/preferences.h b/src/app/pref/preferences.h
index 50e267ec0..944809ce4 100644
--- a/src/app/pref/preferences.h
+++ b/src/app/pref/preferences.h
@@ -16,7 +16,6 @@
#include "app/tools/freehand_algorithm.h"
#include "app/tools/ink_type.h"
#include "app/tools/rotation_algorithm.h"
-#include "app/tools/selection_mode.h"
#include "app/ui/color_bar.h"
#include "doc/anidir.h"
#include "doc/brush_pattern.h"
diff --git a/src/app/tools/controller.h b/src/app/tools/controller.h
index 4206edf3b..643c0c08c 100644
--- a/src/app/tools/controller.h
+++ b/src/app/tools/controller.h
@@ -1,5 +1,5 @@
// Aseprite
-// Copyright (C) 2001-2015 David Capello
+// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@@ -10,7 +10,6 @@
#pragma once
#include "gfx/point.h"
-#include "ui/keys.h"
#include
#include
@@ -30,13 +29,6 @@ namespace app {
virtual bool isFreehand() { return false; }
virtual bool isOnePoint() { return false; }
- virtual void prepareController(ui::KeyModifiers modifiers) { }
-
- // Called when the user presses or releases a key. Returns true
- // if the key is used (so a new mouse point is generated).
- virtual bool pressKey(ui::KeyScancode key) { return false; }
- virtual bool releaseKey(ui::KeyScancode key) { return false; }
-
// Called when the user starts drawing and each time a new button is
// pressed. The controller could be sure that this method is called
// at least one time. The point is a position relative to sprite
diff --git a/src/app/tools/controllers.h b/src/app/tools/controllers.h
index 4601b349e..35bab4bed 100644
--- a/src/app/tools/controllers.h
+++ b/src/app/tools/controllers.h
@@ -1,5 +1,5 @@
// Aseprite
-// Copyright (C) 2001-2015 David Capello
+// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@@ -18,29 +18,15 @@ using namespace gfx;
// using the space bar.
class MoveOriginCapability : public Controller {
public:
- void prepareController(ui::KeyModifiers modifiers) override {
- m_movingOrigin = false;
- }
-
void pressButton(Stroke& stroke, const Point& point) override {
m_last = point;
}
- bool pressKey(ui::KeyScancode key) override {
- TRACE("pressKey(%d)\n", key);
- return processKey(key, true);
- }
-
- bool releaseKey(ui::KeyScancode key) override {
- TRACE("releaseKey(%d)\n", key);
- return processKey(key, false);
- }
-
protected:
- bool isMovingOrigin(Stroke& stroke, const Point& point) {
+ bool isMovingOrigin(ToolLoop* loop, Stroke& stroke, const Point& point) {
bool used = false;
- if (m_movingOrigin) {
+ if (int(loop->getModifiers()) & int(ToolLoopModifiers::kMoveOrigin)) {
Point delta = (point - m_last);
stroke.offset(delta);
@@ -57,18 +43,6 @@ protected:
}
private:
- bool processKey(ui::KeyScancode key, bool state) {
- if (key == ui::kKeySpace) {
- m_movingOrigin = state;
- return true;
- }
- return false;
- }
-
- // Flag used to know if the space bar is pressed, i.e., we have
- // displace all points.
- bool m_movingOrigin;
-
// Last known mouse position used to calculate delta values (dx, dy)
// with the new mouse position to displace all points.
Point m_last;
@@ -120,13 +94,6 @@ public:
// Controls clicks for tools like line
class TwoPointsController : public MoveOriginCapability {
public:
- void prepareController(ui::KeyModifiers modifiers) override {
- MoveOriginCapability::prepareController(modifiers);
-
- m_squareAspect = (modifiers & ui::kKeyShiftModifier) ? true: false;
- m_fromCenter = (modifiers & ui::kKeyCtrlModifier) ? true: false;
- }
-
void pressButton(Stroke& stroke, const Point& point) override {
MoveOriginCapability::pressButton(stroke, point);
@@ -140,31 +107,17 @@ public:
return false;
}
- bool pressKey(ui::KeyScancode key) override {
- if (MoveOriginCapability::pressKey(key))
- return true;
-
- return processKey(key, true);
- }
-
- bool releaseKey(ui::KeyScancode key) override {
- if (MoveOriginCapability::releaseKey(key))
- return true;
-
- return processKey(key, false);
- }
-
void movement(ToolLoop* loop, Stroke& stroke, const Point& point) override {
ASSERT(stroke.size() >= 2);
if (stroke.size() < 2)
return;
- if (MoveOriginCapability::isMovingOrigin(stroke, point))
+ if (MoveOriginCapability::isMovingOrigin(loop, stroke, point))
return;
stroke[1] = point;
- if (m_squareAspect) {
+ if (int(loop->getModifiers()) & int(ToolLoopModifiers::kSquareAspect)) {
int dx = stroke[1].x - m_first.x;
int dy = stroke[1].y - m_first.y;
int minsize = MIN(ABS(dx), ABS(dy));
@@ -209,7 +162,7 @@ public:
stroke[0] = m_first;
- if (m_fromCenter) {
+ if (int(loop->getModifiers()) & int(ToolLoopModifiers::kFromCenter)) {
int rx = stroke[1].x - m_first.x;
int ry = stroke[1].y - m_first.y;
stroke[0].x = m_first.x - rx;
@@ -264,23 +217,7 @@ private:
m_first += delta;
}
- bool processKey(ui::KeyScancode key, bool state) {
- switch (key) {
- case ui::kKeyLShift:
- case ui::kKeyRShift:
- m_squareAspect = state;
- return true;
- case ui::kKeyLControl:
- case ui::kKeyRControl:
- m_fromCenter = state;
- return true;
- }
- return false;
- }
-
Point m_first;
- bool m_squareAspect;
- bool m_fromCenter;
};
// Controls clicks for tools like polygon
@@ -311,7 +248,7 @@ public:
if (stroke.empty())
return;
- if (MoveOriginCapability::isMovingOrigin(stroke, point))
+ if (MoveOriginCapability::isMovingOrigin(loop, stroke, point))
return;
stroke[stroke.size()-1] = point;
@@ -392,7 +329,7 @@ public:
}
void movement(ToolLoop* loop, Stroke& stroke, const Point& point) override {
- if (MoveOriginCapability::isMovingOrigin(stroke, point))
+ if (MoveOriginCapability::isMovingOrigin(loop, stroke, point))
return;
switch (m_clickCounter) {
diff --git a/src/app/tools/inks.h b/src/app/tools/inks.h
index 21e0922f2..4d1d61d43 100644
--- a/src/app/tools/inks.h
+++ b/src/app/tools/inks.h
@@ -1,5 +1,5 @@
// Aseprite
-// Copyright (C) 2001-2015 David Capello
+// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@@ -322,16 +322,15 @@ public:
void inkHline(int x1, int y, int x2, ToolLoop* loop) override {
if (m_modify_selection) {
+ int modifiers = int(loop->getModifiers());
Point origin = loop->getCelOrigin();
- switch (loop->getSelectionMode()) {
- case SelectionMode::DEFAULT:
- case SelectionMode::ADD:
- m_mask.add(gfx::Rect(x1+origin.x, y+origin.y, x2-x1+1, 1));
- break;
- case SelectionMode::SUBTRACT:
- m_mask.subtract(gfx::Rect(x1+origin.x, y+origin.y, x2-x1+1, 1));
- break;
+ if ((modifiers & (int(ToolLoopModifiers::kReplaceSelection) |
+ int(ToolLoopModifiers::kAddSelection))) != 0) {
+ m_mask.add(gfx::Rect(x1+origin.x, y+origin.y, x2-x1+1, 1));
+ }
+ else if ((modifiers & int(ToolLoopModifiers::kSubtractSelection)) != 0) {
+ m_mask.subtract(gfx::Rect(x1+origin.x, y+origin.y, x2-x1+1, 1));
}
m_maxBounds |= gfx::Rect(x1+origin.x, y+origin.y, x2-x1+1, 1);
diff --git a/src/app/tools/selection_mode.h b/src/app/tools/selection_mode.h
deleted file mode 100644
index 09e829dfb..000000000
--- a/src/app/tools/selection_mode.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Aseprite
-// 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 version 2 as
-// published by the Free Software Foundation.
-
-#ifndef APP_TOOLS_SELECTION_MODE_H_INCLUDED
-#define APP_TOOLS_SELECTION_MODE_H_INCLUDED
-#pragma once
-
-namespace app {
-namespace tools {
-
- enum class SelectionMode {
- DEFAULT = 0,
- ADD = 1,
- SUBTRACT = 2,
- };
-
-} // namespace tools
-} // namespace app
-
-#endif
diff --git a/src/app/tools/tool_loop.h b/src/app/tools/tool_loop.h
index 1a5d8f8bf..ae7ab886e 100644
--- a/src/app/tools/tool_loop.h
+++ b/src/app/tools/tool_loop.h
@@ -1,5 +1,5 @@
// Aseprite
-// Copyright (C) 2001-2015 David Capello
+// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@@ -9,7 +9,7 @@
#define APP_TOOLS_TOOL_LOOP_H_INCLUDED
#pragma once
-#include "app/tools/selection_mode.h"
+#include "app/tools/tool_loop_modifiers.h"
#include "app/tools/trace_policy.h"
#include "doc/color.h"
#include "doc/frame.h"
@@ -159,8 +159,9 @@ namespace app {
// contiguous pixels or not.
virtual bool getContiguous() = 0;
- // Returns the selection mode (if the ink is of selection type).
- virtual tools::SelectionMode getSelectionMode() = 0;
+ // Returns flags/modifiers that change the way each part of the
+ // tool (ink/controllers/etc.) work.
+ virtual tools::ToolLoopModifiers getModifiers() = 0;
// Returns the preferred "tiled" mode of the document.
// See the method PointShape::doInkHline to check how this member is
diff --git a/src/app/tools/tool_loop_manager.cpp b/src/app/tools/tool_loop_manager.cpp
index eda557ded..387f34d5d 100644
--- a/src/app/tools/tool_loop_manager.cpp
+++ b/src/app/tools/tool_loop_manager.cpp
@@ -48,8 +48,7 @@ bool ToolLoopManager::isCanceled() const
return m_toolLoop->isCanceled();
}
-void ToolLoopManager::prepareLoop(const Pointer& pointer,
- ui::KeyModifiers modifiers)
+void ToolLoopManager::prepareLoop(const Pointer& pointer)
{
// Start with no points at all
m_stroke.reset();
@@ -57,35 +56,16 @@ void ToolLoopManager::prepareLoop(const Pointer& pointer,
// Prepare the ink
m_toolLoop->getInk()->prepareInk(m_toolLoop);
m_toolLoop->getIntertwine()->prepareIntertwine();
- m_toolLoop->getController()->prepareController(modifiers);
m_toolLoop->getPointShape()->preparePointShape(m_toolLoop);
}
-void ToolLoopManager::pressKey(ui::KeyScancode key)
+void ToolLoopManager::notifyToolLoopModifiersChange()
{
if (isCanceled())
return;
- if (m_toolLoop->getController()->pressKey(key)) {
- if (m_lastPointer.getButton() != Pointer::None)
- movement(m_lastPointer);
- }
-}
-
-void ToolLoopManager::releaseKey(ui::KeyScancode key)
-{
- if (isCanceled())
- return;
-
- if (key == ui::kKeyEsc) {
- m_toolLoop->cancel();
- return;
- }
-
- if (m_toolLoop->getController()->releaseKey(key)) {
- if (m_lastPointer.getButton() != Pointer::None)
- movement(m_lastPointer);
- }
+ if (m_lastPointer.getButton() != Pointer::None)
+ movement(m_lastPointer);
}
void ToolLoopManager::pressButton(const Pointer& pointer)
diff --git a/src/app/tools/tool_loop_manager.h b/src/app/tools/tool_loop_manager.h
index 063d19172..8de18230f 100644
--- a/src/app/tools/tool_loop_manager.h
+++ b/src/app/tools/tool_loop_manager.h
@@ -1,5 +1,5 @@
// Aseprite
-// Copyright (C) 2001-2015 David Capello
+// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@@ -12,7 +12,6 @@
#include "app/tools/stroke.h"
#include "gfx/point.h"
#include "gfx/region.h"
-#include "ui/keys.h"
#include
@@ -69,11 +68,11 @@ namespace app {
// Should be called when the user start a tool-trace (pressing the
// left or right button for first time in the editor).
- void prepareLoop(const Pointer& pointer,
- ui::KeyModifiers modifiers);
+ void prepareLoop(const Pointer& pointer);
- void pressKey(ui::KeyScancode key);
- void releaseKey(ui::KeyScancode key);
+ // Should be called when the ToolLoop::getModifiers()
+ // value was modified (e.g. when the user press/release a key).
+ void notifyToolLoopModifiersChange();
// Should be called each time the user presses a mouse button.
void pressButton(const Pointer& pointer);
diff --git a/src/app/tools/tool_loop_modifiers.h b/src/app/tools/tool_loop_modifiers.h
new file mode 100644
index 000000000..88bdffafa
--- /dev/null
+++ b/src/app/tools/tool_loop_modifiers.h
@@ -0,0 +1,28 @@
+// Aseprite
+// Copyright (C) 2016 David Capello
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+
+#ifndef APP_TOOLS_TOOL_LOOP_MODIFIERS_H_INCLUDED
+#define APP_TOOLS_TOOL_LOOP_MODIFIERS_H_INCLUDED
+#pragma once
+
+namespace app {
+namespace tools {
+
+ enum class ToolLoopModifiers {
+ kNone = 0x00000000,
+ kReplaceSelection = 0x00000001,
+ kAddSelection = 0x00000002,
+ kSubtractSelection = 0x00000004,
+ kMoveOrigin = 0x00000008,
+ kSquareAspect = 0x00000010,
+ kFromCenter = 0x00000020,
+ };
+
+} // namespace tools
+} // namespace app
+
+#endif
diff --git a/src/app/ui/context_bar.cpp b/src/app/ui/context_bar.cpp
index 751a6805f..4b0672b26 100644
--- a/src/app/ui/context_bar.cpp
+++ b/src/app/ui/context_bar.cpp
@@ -27,9 +27,9 @@
#include "app/tools/ink.h"
#include "app/tools/ink_type.h"
#include "app/tools/point_shape.h"
-#include "app/tools/selection_mode.h"
#include "app/tools/tool.h"
#include "app/tools/tool_box.h"
+#include "app/tools/tool_loop_modifiers.h"
#include "app/ui/brush_popup.h"
#include "app/ui/button_set.h"
#include "app/ui/color_button.h"
@@ -1110,7 +1110,7 @@ public:
tooltipManager->addTooltipFor(at(2), "Subtract from selection\n(Shift+Alt)", BOTTOM);
}
- void setSelectionMode(SelectionMode mode) {
+ void setSelectionMode(gen::SelectionMode mode) {
setSelectedItem((int)mode);
invalidate();
}
@@ -1120,7 +1120,7 @@ protected:
ButtonSet::onItemChange(item);
Preferences::instance().selection.mode(
- (tools::SelectionMode)selectedItem());
+ (gen::SelectionMode)selectedItem());
}
};
@@ -1624,11 +1624,17 @@ void ContextBar::updateForSelectingBox(const std::string& text)
layout();
}
-void ContextBar::updateSelectionMode(SelectionMode mode)
+void ContextBar::updateToolLoopModifiersIndicators(tools::ToolLoopModifiers modifiers)
{
if (!m_selectionMode->isVisible())
return;
+ gen::SelectionMode mode = gen::SelectionMode::DEFAULT;
+ if (int(modifiers) & int(tools::ToolLoopModifiers::kAddSelection))
+ mode = gen::SelectionMode::ADD;
+ else if (int(modifiers) & int(tools::ToolLoopModifiers::kSubtractSelection))
+ mode = gen::SelectionMode::SUBTRACT;
+
m_selectionMode->setSelectionMode(mode);
}
diff --git a/src/app/ui/context_bar.h b/src/app/ui/context_bar.h
index 6424a2cb4..add5091e0 100644
--- a/src/app/ui/context_bar.h
+++ b/src/app/ui/context_bar.h
@@ -12,7 +12,7 @@
#include "app/pref/preferences.h"
#include "app/shade.h"
#include "app/tools/ink_type.h"
-#include "app/tools/selection_mode.h"
+#include "app/tools/tool_loop_modifiers.h"
#include "app/ui/context_bar_observer.h"
#include "base/connection.h"
#include "base/observable.h"
@@ -48,7 +48,7 @@ namespace app {
void updateForTool(tools::Tool* tool);
void updateForMovingPixels();
void updateForSelectingBox(const std::string& text);
- void updateSelectionMode(app::tools::SelectionMode mode);
+ void updateToolLoopModifiersIndicators(app::tools::ToolLoopModifiers modifiers);
void updateAutoSelectLayer(bool state);
void setActiveBrush(const doc::BrushRef& brush);
diff --git a/src/app/ui/editor/brush_preview.cpp b/src/app/ui/editor/brush_preview.cpp
index fe0c35b66..10d6eb354 100644
--- a/src/app/ui/editor/brush_preview.cpp
+++ b/src/app/ui/editor/brush_preview.cpp
@@ -207,7 +207,6 @@ void BrushPreview::show(const gfx::Point& screenPos)
if (loop) {
loop->getInk()->prepareInk(loop);
loop->getIntertwine()->prepareIntertwine();
- loop->getController()->prepareController(ui::kKeyNoneModifier);
loop->getPointShape()->preparePointShape(loop);
loop->getPointShape()->transformPoint(
loop, -origBrushBounds.x, -origBrushBounds.y);
diff --git a/src/app/ui/editor/drawing_state.cpp b/src/app/ui/editor/drawing_state.cpp
index b342d597a..a6703be70 100644
--- a/src/app/ui/editor/drawing_state.cpp
+++ b/src/app/ui/editor/drawing_state.cpp
@@ -94,7 +94,7 @@ void DrawingState::initToolLoop(Editor* editor, MouseMessage* msg)
pointer = pointer_from_msg(editor, msg);
}
- m_toolLoopManager->prepareLoop(pointer, msg->modifiers());
+ m_toolLoopManager->prepareLoop(pointer);
m_toolLoopManager->pressButton(pointer);
// This first movement is done when the user pressed Shift+click in
@@ -108,6 +108,12 @@ void DrawingState::initToolLoop(Editor* editor, MouseMessage* msg)
editor->captureMouse();
}
+void DrawingState::notifyToolLoopModifiersChange(Editor* editor)
+{
+ if (!m_toolLoopManager->isCanceled())
+ m_toolLoopManager->notifyToolLoopModifiersChange();
+}
+
bool DrawingState::onMouseDown(Editor* editor, MouseMessage* msg)
{
// Drawing loop
@@ -190,9 +196,6 @@ bool DrawingState::onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos)
bool DrawingState::onKeyDown(Editor* editor, KeyMessage* msg)
{
- if (msg->repeat() == 0)
- m_toolLoopManager->pressKey(msg->scancode());
-
Command* command = NULL;
Params params;
if (KeyboardShortcuts::instance()
@@ -208,7 +211,8 @@ bool DrawingState::onKeyDown(Editor* editor, KeyMessage* msg)
bool DrawingState::onKeyUp(Editor* editor, KeyMessage* msg)
{
- m_toolLoopManager->releaseKey(msg->scancode());
+ if (msg->scancode() == ui::kKeyEsc)
+ m_toolLoop->cancel();
// The user might have canceled the tool loop pressing the 'Esc' key.
destroyLoopIfCanceled(editor);
diff --git a/src/app/ui/editor/drawing_state.h b/src/app/ui/editor/drawing_state.h
index 7339057c4..1ff9c5e66 100644
--- a/src/app/ui/editor/drawing_state.h
+++ b/src/app/ui/editor/drawing_state.h
@@ -35,6 +35,7 @@ namespace app {
virtual bool requireBrushPreview() override { return false; }
void initToolLoop(Editor* editor, ui::MouseMessage* msg);
+ void notifyToolLoopModifiersChange(Editor* editor);
private:
void destroyLoopIfCanceled(Editor* editor);
diff --git a/src/app/ui/editor/editor.cpp b/src/app/ui/editor/editor.cpp
index 6310924c4..13030bf39 100644
--- a/src/app/ui/editor/editor.cpp
+++ b/src/app/ui/editor/editor.cpp
@@ -30,6 +30,7 @@
#include "app/tools/tool_box.h"
#include "app/ui/color_bar.h"
#include "app/ui/context_bar.h"
+#include "app/ui/editor/drawing_state.h"
#include "app/ui/editor/editor_customization_delegate.h"
#include "app/ui/editor/editor_decorator.h"
#include "app/ui/editor/moving_pixels_state.h"
@@ -157,7 +158,7 @@ Editor::Editor(Document* document, EditorFlags flags)
, m_brushPreview(this)
, m_lastDrawingPosition(-1, -1)
, m_quicktool(NULL)
- , m_selectionMode(tools::SelectionMode::DEFAULT)
+ , m_toolLoopModifiers(tools::ToolLoopModifiers::kNone)
, m_padding(0, 0)
, m_antsTimer(100, this)
, m_antsOffset(0)
@@ -1110,7 +1111,7 @@ void Editor::updateStatusBar()
void Editor::updateQuicktool()
{
- if (m_customizationDelegate) {
+ if (m_customizationDelegate && !hasCapture()) {
tools::Tool* current_tool = App::instance()->activeTool();
// Don't change quicktools if we are in a selection tool and using
@@ -1156,42 +1157,67 @@ void Editor::updateQuicktool()
}
}
-void Editor::updateContextBarFromModifiers()
+void Editor::updateToolLoopModifiersIndicators()
{
- // We update the selection mode only if we're not selecting.
- if (hasCapture())
- return;
+ int modifiers = int(tools::ToolLoopModifiers::kNone);
+ bool autoSelectLayer = Preferences::instance().editor.autoSelectLayer();
+ KeyAction action;
+
+ if (m_customizationDelegate) {
+ // When the mouse is captured, is when we are scrolling, or
+ // drawing, or moving, or selecting, etc. So several
+ // parameters/tool-loop-modifiers are static.
+ if (hasCapture()) {
+ modifiers |= (int(m_toolLoopModifiers) &
+ (int(tools::ToolLoopModifiers::kReplaceSelection) |
+ int(tools::ToolLoopModifiers::kAddSelection) |
+ int(tools::ToolLoopModifiers::kSubtractSelection)));
+ autoSelectLayer = m_autoSelectLayer;
+
+ // Shape tools (line, curves, rectangles, etc.)
+ action = m_customizationDelegate->getPressedKeyAction(KeyContext::ShapeTool);
+ if (int(action & KeyAction::MoveOrigin))
+ modifiers |= int(tools::ToolLoopModifiers::kMoveOrigin);
+ if (int(action & KeyAction::SquareAspect))
+ modifiers |= int(tools::ToolLoopModifiers::kSquareAspect);
+ if (int(action & KeyAction::DrawFromCenter))
+ modifiers |= int(tools::ToolLoopModifiers::kFromCenter);
+ }
+ else {
+ // We update the selection mode only if we're not selecting.
+ action = m_customizationDelegate->getPressedKeyAction(KeyContext::SelectionTool);
+
+ gen::SelectionMode mode = Preferences::instance().selection.mode();
+ if (int(action & KeyAction::AddSelection))
+ mode = gen::SelectionMode::ADD;
+ if (int(action & KeyAction::SubtractSelection) || m_secondaryButton)
+ mode = gen::SelectionMode::SUBTRACT;
+ switch (mode) {
+ case gen::SelectionMode::DEFAULT: modifiers |= int(tools::ToolLoopModifiers::kReplaceSelection); break;
+ case gen::SelectionMode::ADD: modifiers |= int(tools::ToolLoopModifiers::kAddSelection); break;
+ case gen::SelectionMode::SUBTRACT: modifiers |= int(tools::ToolLoopModifiers::kSubtractSelection); break;
+ }
+
+ // For move tool
+ action = m_customizationDelegate->getPressedKeyAction(KeyContext::MoveTool);
+ if (int(action & KeyAction::AutoSelectLayer))
+ autoSelectLayer = true;
+ }
+ }
ContextBar* ctxBar = App::instance()->getMainWindow()->getContextBar();
- // Selection mode
+ if (int(m_toolLoopModifiers) != modifiers) {
+ m_toolLoopModifiers = tools::ToolLoopModifiers(modifiers);
- tools::SelectionMode mode = Preferences::instance().selection.mode();
+ // TODO the contextbar should be a observer of the current editor
+ ctxBar->updateToolLoopModifiersIndicators(m_toolLoopModifiers);
- KeyAction action = KeyAction::None;
- if (m_customizationDelegate)
- action = m_customizationDelegate->getPressedKeyAction(KeyContext::SelectionTool);
-
- if (int(action & KeyAction::AddSelection))
- mode = tools::SelectionMode::ADD;
- if (int(action & KeyAction::SubtractSelection))
- mode = tools::SelectionMode::SUBTRACT;
- else if (m_secondaryButton)
- mode = tools::SelectionMode::SUBTRACT;
-
- if (mode != m_selectionMode) {
- m_selectionMode = mode;
- ctxBar->updateSelectionMode(mode);
+ if (auto drawingState = dynamic_cast(m_state.get())) {
+ drawingState->notifyToolLoopModifiersChange(this);
+ }
}
- // Move tool options
-
- bool autoSelectLayer = Preferences::instance().editor.autoSelectLayer();
-
- if ((m_customizationDelegate) &&
- int(m_customizationDelegate->getPressedKeyAction(KeyContext::MoveTool) & KeyAction::AutoSelectLayer))
- autoSelectLayer = true;
-
if (m_autoSelectLayer != autoSelectLayer) {
m_autoSelectLayer = autoSelectLayer;
ctxBar->updateAutoSelectLayer(autoSelectLayer);
@@ -1238,7 +1264,7 @@ bool Editor::onProcessMessage(Message* msg)
case kMouseEnterMessage:
updateQuicktool();
- updateContextBarFromModifiers();
+ updateToolLoopModifiersIndicators();
break;
case kMouseLeaveMessage:
@@ -1255,7 +1281,7 @@ bool Editor::onProcessMessage(Message* msg)
m_secondaryButton = mouseMsg->right();
updateQuicktool();
- updateContextBarFromModifiers();
+ updateToolLoopModifiersIndicators();
setCursor(mouseMsg->position());
}
@@ -1281,7 +1307,7 @@ bool Editor::onProcessMessage(Message* msg)
m_secondaryButton = false;
updateQuicktool();
- updateContextBarFromModifiers();
+ updateToolLoopModifiersIndicators();
setCursor(mouseMsg->position());
}
@@ -1314,9 +1340,9 @@ bool Editor::onProcessMessage(Message* msg)
if (hasMouse()) {
updateQuicktool();
- updateContextBarFromModifiers();
setCursor(ui::get_mouse_position());
}
+ updateToolLoopModifiersIndicators();
if (used)
return true;
@@ -1330,9 +1356,9 @@ bool Editor::onProcessMessage(Message* msg)
if (hasMouse()) {
updateQuicktool();
- updateContextBarFromModifiers();
setCursor(ui::get_mouse_position());
}
+ updateToolLoopModifiersIndicators();
if (used)
return true;
@@ -1481,7 +1507,7 @@ bool Editor::isInsideSelection()
{
gfx::Point spritePos = screenToEditor(ui::get_mouse_position());
return
- (m_selectionMode != tools::SelectionMode::SUBTRACT) &&
+ ((int(m_toolLoopModifiers) & int(tools::ToolLoopModifiers::kSubtractSelection)) == 0) &&
m_document != NULL &&
m_document->isMaskVisible() &&
m_document->mask()->containsPoint(spritePos.x, spritePos.y);
diff --git a/src/app/ui/editor/editor.h b/src/app/ui/editor/editor.h
index 7a2e0af95..ba04e359f 100644
--- a/src/app/ui/editor/editor.h
+++ b/src/app/ui/editor/editor.h
@@ -13,7 +13,7 @@
#include "app/color.h"
#include "app/document.h"
#include "app/pref/preferences.h"
-#include "app/tools/selection_mode.h"
+#include "app/tools/tool_loop_modifiers.h"
#include "app/ui/color_source.h"
#include "app/ui/editor/brush_preview.h"
#include "app/ui/editor/editor_observers.h"
@@ -173,9 +173,8 @@ namespace app {
tools::Tool* getCurrentEditorTool();
tools::Ink* getCurrentEditorInk();
- tools::SelectionMode getSelectionMode() const { return m_selectionMode; }
+ tools::ToolLoopModifiers getToolLoopModifiers() const { return m_toolLoopModifiers; }
bool isAutoSelectLayer() const { return m_autoSelectLayer; }
-
bool isSecondaryButton() const { return m_secondaryButton; }
gfx::Point lastDrawingPosition() const { return m_lastDrawingPosition; }
@@ -241,7 +240,7 @@ namespace app {
private:
void setStateInternal(const EditorStatePtr& newState);
void updateQuicktool();
- void updateContextBarFromModifiers();
+ void updateToolLoopModifiersIndicators();
bool isCurrentToolAffectedByRightClickMode();
void drawMaskSafe();
@@ -288,7 +287,7 @@ namespace app {
// the user is not pressing any keyboard key).
tools::Tool* m_quicktool;
- tools::SelectionMode m_selectionMode;
+ tools::ToolLoopModifiers m_toolLoopModifiers;
bool m_autoSelectLayer;
// Extra space around the sprite.
diff --git a/src/app/ui/editor/standby_state.cpp b/src/app/ui/editor/standby_state.cpp
index 7aebb9704..1244198f1 100644
--- a/src/app/ui/editor/standby_state.cpp
+++ b/src/app/ui/editor/standby_state.cpp
@@ -350,14 +350,10 @@ bool StandbyState::onDoubleClick(Editor* editor, MouseMessage* msg)
CommandsModule::instance()->getCommandByName(CommandId::SelectTile);
Params params;
- switch (editor->getSelectionMode()) {
- case tools::SelectionMode::ADD:
- params.set("mode", "add");
- break;
- case tools::SelectionMode::SUBTRACT:
- params.set("mode", "subtract");
- break;
- }
+ if (int(editor->getToolLoopModifiers()) & int(tools::ToolLoopModifiers::kAddSelection))
+ params.set("mode", "add");
+ else if (int(editor->getToolLoopModifiers()) & int(tools::ToolLoopModifiers::kSubtractSelection))
+ params.set("mode", "subtract");
UIContext::instance()->executeCommand(selectTileCmd, params);
return true;
diff --git a/src/app/ui/editor/tool_loop_impl.cpp b/src/app/ui/editor/tool_loop_impl.cpp
index 70a0bee26..59be09747 100644
--- a/src/app/ui/editor/tool_loop_impl.cpp
+++ b/src/app/ui/editor/tool_loop_impl.cpp
@@ -203,7 +203,7 @@ public:
int getOpacity() override { return m_opacity; }
int getTolerance() override { return m_tolerance; }
bool getContiguous() override { return m_contiguous; }
- tools::SelectionMode getSelectionMode() override { return m_editor->getSelectionMode(); }
+ tools::ToolLoopModifiers getModifiers() override { return m_editor->getToolLoopModifiers(); }
filters::TiledMode getTiledMode() override { return m_docPref.tiled.mode(); }
bool getGridVisible() override { return m_docPref.show.grid(); }
bool getSnapToGrid() override { return m_docPref.grid.snap(); }
@@ -324,7 +324,7 @@ public:
// Start with an empty mask if the user is selecting with "default selection mode"
if (getInk()->isSelection() &&
(!m_document->isMaskVisible() ||
- getSelectionMode() == tools::SelectionMode::DEFAULT)) {
+ (int(getModifiers()) & int(tools::ToolLoopModifiers::kReplaceSelection)))) {
Mask emptyMask;
m_transaction.execute(new cmd::SetMask(m_document, &emptyMask));
}
diff --git a/src/app/ui/keyboard_shortcuts.cpp b/src/app/ui/keyboard_shortcuts.cpp
index 7089f9fad..d9f895c62 100644
--- a/src/app/ui/keyboard_shortcuts.cpp
+++ b/src/app/ui/keyboard_shortcuts.cpp
@@ -1,5 +1,5 @@
// Aseprite
-// Copyright (C) 2001-2015 David Capello
+// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@@ -42,8 +42,11 @@ namespace {
{ "LockAxis" , "Lock Axis" , app::KeyAction::LockAxis },
{ "AddSelection" , "Add Selection" , app::KeyAction::AddSelection },
{ "SubtractSelection" , "Subtract Selection" , app::KeyAction::SubtractSelection },
- { "AutoSelectLayer" , "Auto Select Layer" , app::KeyAction::AutoSelectLayer },
+ { "AutoSelectLayer" , "Auto Select Layer" , app::KeyAction::AutoSelectLayer },
{ "StraightLineFromLastPoint", "Straight Line from Last Point", app::KeyAction::StraightLineFromLastPoint },
+ { "MoveOrigin" , "Move Origin" , app::KeyAction::MoveOrigin },
+ { "SquareAspect" , "Square Aspect" , app::KeyAction::SquareAspect },
+ { "DrawFromCenter" , "Draw From Center" , app::KeyAction::DrawFromCenter },
{ "LeftMouseButton" , "Trigger Left Mouse Button" , app::KeyAction::LeftMouseButton },
{ "RightMouseButton" , "Trigger Right Mouse Button" , app::KeyAction::RightMouseButton },
{ NULL , NULL , app::KeyAction::None }
@@ -136,9 +139,8 @@ Key::Key(KeyAction action)
m_keycontext = KeyContext::Any;
break;
case KeyAction::CopySelection:
- m_keycontext = KeyContext::TranslatingSelection;
- break;
case KeyAction::SnapToGrid:
+ case KeyAction::LockAxis:
m_keycontext = KeyContext::TranslatingSelection;
break;
case KeyAction::AngleSnap:
@@ -147,12 +149,7 @@ Key::Key(KeyAction action)
case KeyAction::MaintainAspectRatio:
m_keycontext = KeyContext::ScalingSelection;
break;
- case KeyAction::LockAxis:
- m_keycontext = KeyContext::TranslatingSelection;
- break;
case KeyAction::AddSelection:
- m_keycontext = KeyContext::SelectionTool;
- break;
case KeyAction::SubtractSelection:
m_keycontext = KeyContext::SelectionTool;
break;
@@ -162,6 +159,11 @@ Key::Key(KeyAction action)
case KeyAction::StraightLineFromLastPoint:
m_keycontext = KeyContext::FreehandTool;
break;
+ case KeyAction::MoveOrigin:
+ case KeyAction::SquareAspect:
+ case KeyAction::DrawFromCenter:
+ m_keycontext = KeyContext::ShapeTool;
+ break;
case KeyAction::LeftMouseButton:
m_keycontext = KeyContext::Any;
break;
@@ -538,6 +540,9 @@ void KeyboardShortcuts::exportAccel(TiXmlElement& parent, Key* key, const ui::Ac
case KeyContext::FreehandTool:
keycontextStr = "FreehandTool";
break;
+ case KeyContext::ShapeTool:
+ keycontextStr = "ShapeTool";
+ break;
}
if (keycontextStr)
diff --git a/src/app/ui/keyboard_shortcuts.h b/src/app/ui/keyboard_shortcuts.h
index b82f2dcd4..bd53a4c64 100644
--- a/src/app/ui/keyboard_shortcuts.h
+++ b/src/app/ui/keyboard_shortcuts.h
@@ -1,5 +1,5 @@
// Aseprite
-// Copyright (C) 2001-2015 David Capello
+// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@@ -39,6 +39,7 @@ namespace app {
RotatingSelection,
MoveTool,
FreehandTool,
+ ShapeTool,
};
enum class KeySource {
@@ -66,7 +67,10 @@ namespace app {
AutoSelectLayer = 0x00000080,
LeftMouseButton = 0x00000100,
RightMouseButton = 0x00000200,
- StraightLineFromLastPoint = 0x00000400
+ StraightLineFromLastPoint = 0x00000400,
+ MoveOrigin = 0x00000800,
+ SquareAspect = 0x00001000,
+ DrawFromCenter = 0x00002000,
};
inline KeyAction operator&(KeyAction a, KeyAction b) {