diff --git a/data/extensions/aseprite-theme/sheet.png b/data/extensions/aseprite-theme/sheet.png
index 3e4d6fa65..0e33ccf87 100644
Binary files a/data/extensions/aseprite-theme/sheet.png and b/data/extensions/aseprite-theme/sheet.png differ
diff --git a/data/extensions/aseprite-theme/theme.xml b/data/extensions/aseprite-theme/theme.xml
index 627bc957b..833f8cbe3 100644
--- a/data/extensions/aseprite-theme/theme.xml
+++ b/data/extensions/aseprite-theme/theme.xml
@@ -244,6 +244,7 @@
+
diff --git a/data/gui.xml b/data/gui.xml
index c86a8e00c..46559b52b 100644
--- a/data/gui.xml
+++ b/data/gui.xml
@@ -1,6 +1,7 @@
-
+
+
@@ -449,6 +450,9 @@
+
+
+
@@ -543,7 +547,8 @@
-
+
+
diff --git a/data/pref.xml b/data/pref.xml
index 93b0d6541..03d22a1c9 100644
--- a/data/pref.xml
+++ b/data/pref.xml
@@ -68,6 +68,7 @@
+
diff --git a/data/strings/en.ini b/data/strings/en.ini
index 19fc02588..a40267d4b 100644
--- a/data/strings/en.ini
+++ b/data/strings/en.ini
@@ -380,6 +380,7 @@ ScrollCenter = Scroll to center of canvas
SelectTile = Select Tile
SelectTile_Add = Select Tile (Add)
SelectTile_Subtract = Select Tile (Subtract)
+SelectTile_Intersect = Select Tile (Intersect)
SelectionAsGrid = Selection as Grid
SetColorSelector = Set Color Selector
SetColorSelector_Spectrum = Color Spectrum
diff --git a/src/app/commands/cmd_select_tile.cpp b/src/app/commands/cmd_select_tile.cpp
index 8977a9178..f49d3f30e 100644
--- a/src/app/commands/cmd_select_tile.cpp
+++ b/src/app/commands/cmd_select_tile.cpp
@@ -1,4 +1,5 @@
// Aseprite
+// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2015-2018 David Capello
//
// This program is distributed under the terms of
@@ -55,6 +56,8 @@ void SelectTileCommand::onLoadParams(const Params& params)
m_mode = gen::SelectionMode::ADD;
else if (mode == "subtract")
m_mode = gen::SelectionMode::SUBTRACT;
+ else if (mode == "intersect")
+ m_mode = gen::SelectionMode::INTERSECT;
else
m_mode = gen::SelectionMode::DEFAULT;
}
@@ -86,10 +89,18 @@ void SelectTileCommand::onExecute(Context* ctx)
pos = snap_to_grid(gridBounds, pos, PreferSnapTo::BoxOrigin);
gridBounds.setOrigin(pos);
- if (m_mode != gen::SelectionMode::SUBTRACT)
- mask->add(gridBounds);
- else
- mask->subtract(gridBounds);
+ switch (m_mode) {
+ case gen::SelectionMode::DEFAULT:
+ case gen::SelectionMode::ADD:
+ mask->add(gridBounds);
+ break;
+ case gen::SelectionMode::SUBTRACT:
+ mask->subtract(gridBounds);
+ break;
+ case gen::SelectionMode::INTERSECT:
+ mask->intersect(gridBounds);
+ break;
+ }
}
// Set the new mask
@@ -113,8 +124,11 @@ std::string SelectTileCommand::onGetFriendlyName() const
case gen::SelectionMode::SUBTRACT:
text = Strings::commands_SelectTile_Subtract();
break;
+ case gen::SelectionMode::INTERSECT:
+ text = Strings::commands_SelectTile_Intersect();
+ break;
default:
- text = getBaseFriendlyName();;
+ text = getBaseFriendlyName();
break;
}
return text;
diff --git a/src/app/tools/inks.h b/src/app/tools/inks.h
index f6a4eb3f2..f144525e6 100644
--- a/src/app/tools/inks.h
+++ b/src/app/tools/inks.h
@@ -362,6 +362,7 @@ public:
class SelectionInk : public BaseInk {
bool m_modify_selection;
Mask m_mask;
+ Mask m_intersectMask;
Rect m_maxBounds;
public:
@@ -390,6 +391,9 @@ public:
else if ((modifiers & int(ToolLoopModifiers::kSubtractSelection)) != 0) {
m_mask.subtract(gfx::Rect(x1, y, x2-x1+1, 1));
}
+ else if ((modifiers & int(ToolLoopModifiers::kIntersectSelection)) != 0) {
+ m_intersectMask.add(gfx::Rect(x1, y, x2-x1+1, 1));
+ }
m_maxBounds |= gfx::Rect(x1, y, x2-x1+1, 1);
}
@@ -409,6 +413,11 @@ public:
m_mask.reserve(loop->sprite()->bounds());
}
else {
+ int modifiers = int(loop->getModifiers());
+ if ((modifiers & int(ToolLoopModifiers::kIntersectSelection)) != 0) {
+ m_mask.intersect(m_intersectMask);
+ }
+
// We can intersect the used bounds in inkHline() calls to
// reduce the shrink computation.
m_mask.intersect(m_maxBounds);
diff --git a/src/app/tools/tool_loop_modifiers.h b/src/app/tools/tool_loop_modifiers.h
index 769b82d6d..7c355457a 100644
--- a/src/app/tools/tool_loop_modifiers.h
+++ b/src/app/tools/tool_loop_modifiers.h
@@ -1,4 +1,5 @@
// Aseprite
+// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2016-2018 David Capello
//
// This program is distributed under the terms of
@@ -16,10 +17,11 @@ namespace tools {
kReplaceSelection = 0x00000001,
kAddSelection = 0x00000002,
kSubtractSelection = 0x00000004,
- kMoveOrigin = 0x00000008,
- kSquareAspect = 0x00000010,
- kFromCenter = 0x00000020,
- kRotateShape = 0x00000040,
+ kIntersectSelection = 0x00000008,
+ kMoveOrigin = 0x00000010,
+ kSquareAspect = 0x00000020,
+ kFromCenter = 0x00000040,
+ kRotateShape = 0x00000080,
};
} // namespace tools
diff --git a/src/app/ui/context_bar.cpp b/src/app/ui/context_bar.cpp
index b9821b205..ce45d8ed1 100644
--- a/src/app/ui/context_bar.cpp
+++ b/src/app/ui/context_bar.cpp
@@ -1,4 +1,5 @@
// Aseprite
+// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@@ -926,12 +927,13 @@ protected:
class ContextBar::SelectionModeField : public ButtonSet {
public:
- SelectionModeField() : ButtonSet(3) {
+ SelectionModeField() : ButtonSet(4) {
SkinTheme* theme = static_cast(this->theme());
addItem(theme->parts.selectionReplace());
addItem(theme->parts.selectionAdd());
addItem(theme->parts.selectionSubtract());
+ addItem(theme->parts.selectionIntersect());
setSelectedItem((int)Preferences::instance().selection.mode());
}
@@ -945,6 +947,9 @@ public:
tooltipManager->addTooltipFor(
at(2), key_tooltip("Subtract from selection", KeyAction::SubtractSelection), BOTTOM);
+
+ tooltipManager->addTooltipFor(
+ at(3), key_tooltip("Intersect selection", KeyAction::IntersectSelection), BOTTOM);
}
void setSelectionMode(gen::SelectionMode mode) {
@@ -1510,6 +1515,8 @@ void ContextBar::updateToolLoopModifiersIndicators(tools::ToolLoopModifiers modi
mode = gen::SelectionMode::ADD;
else if (int(modifiers) & int(tools::ToolLoopModifiers::kSubtractSelection))
mode = gen::SelectionMode::SUBTRACT;
+ else if (int(modifiers) & int(tools::ToolLoopModifiers::kIntersectSelection))
+ mode = gen::SelectionMode::INTERSECT;
m_selectionMode->setSelectionMode(mode);
}
diff --git a/src/app/ui/editor/drawing_state.cpp b/src/app/ui/editor/drawing_state.cpp
index 7944cd477..809d00e03 100644
--- a/src/app/ui/editor/drawing_state.cpp
+++ b/src/app/ui/editor/drawing_state.cpp
@@ -1,4 +1,5 @@
// Aseprite
+// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@@ -153,7 +154,8 @@ bool DrawingState::onMouseUp(Editor* editor, MouseMessage* msg)
if (!m_toolLoop->getInk()->isSelection() ||
m_toolLoop->getController()->isOnePoint() ||
m_mouseMoveReceived ||
- editor->getToolLoopModifiers() != tools::ToolLoopModifiers::kReplaceSelection) {
+ (editor->getToolLoopModifiers() != tools::ToolLoopModifiers::kReplaceSelection &&
+ editor->getToolLoopModifiers() != tools::ToolLoopModifiers::kIntersectSelection)) {
// Notify the release of the mouse button to the tool loop
// manager. This is the correct way to say "the user finishes the
// drawing trace correctly".
diff --git a/src/app/ui/editor/editor.cpp b/src/app/ui/editor/editor.cpp
index 06127d78d..941f020f2 100644
--- a/src/app/ui/editor/editor.cpp
+++ b/src/app/ui/editor/editor.cpp
@@ -1496,7 +1496,8 @@ void Editor::updateToolLoopModifiersIndicators()
modifiers |= (int(m_toolLoopModifiers) &
(int(tools::ToolLoopModifiers::kReplaceSelection) |
int(tools::ToolLoopModifiers::kAddSelection) |
- int(tools::ToolLoopModifiers::kSubtractSelection)));
+ int(tools::ToolLoopModifiers::kSubtractSelection) |
+ int(tools::ToolLoopModifiers::kIntersectSelection)));
tools::Controller* controller =
(App::instance()->activeToolManager()->selectedTool() ?
@@ -1535,13 +1536,17 @@ void Editor::updateToolLoopModifiersIndicators()
App::instance()->activeToolManager()->selectedTool()->getInk(0)->isSelection())) {
mode = gen::SelectionMode::SUBTRACT;
}
+ else if (int(action & KeyAction::IntersectSelection)) {
+ mode = gen::SelectionMode::INTERSECT;
+ }
else if (int(action & KeyAction::AddSelection)) {
mode = gen::SelectionMode::ADD;
}
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;
+ 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;
+ case gen::SelectionMode::INTERSECT: modifiers |= int(tools::ToolLoopModifiers::kIntersectSelection); break;
}
// For move tool
diff --git a/src/app/ui/editor/standby_state.cpp b/src/app/ui/editor/standby_state.cpp
index 4667151c0..13a43e969 100644
--- a/src/app/ui/editor/standby_state.cpp
+++ b/src/app/ui/editor/standby_state.cpp
@@ -1,4 +1,5 @@
// Aseprite
+// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@@ -386,6 +387,8 @@ bool StandbyState::onDoubleClick(Editor* editor, MouseMessage* msg)
params.set("mode", "add");
else if (int(editor->getToolLoopModifiers()) & int(tools::ToolLoopModifiers::kSubtractSelection))
params.set("mode", "subtract");
+ else if (int(editor->getToolLoopModifiers()) & int(tools::ToolLoopModifiers::kIntersectSelection))
+ params.set("mode", "intersect");
UIContext::instance()->executeCommand(selectTileCmd, params);
return true;
diff --git a/src/app/ui/key.h b/src/app/ui/key.h
index e6ce5b51e..7ff1f41ec 100644
--- a/src/app/ui/key.h
+++ b/src/app/ui/key.h
@@ -1,4 +1,5 @@
// Aseprite
+// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@@ -51,16 +52,17 @@ namespace app {
LockAxis = 0x00000010,
AddSelection = 0x00000020,
SubtractSelection = 0x00000040,
- AutoSelectLayer = 0x00000080,
- LeftMouseButton = 0x00000100,
- RightMouseButton = 0x00000200,
- StraightLineFromLastPoint = 0x00000400,
- MoveOrigin = 0x00000800,
- SquareAspect = 0x00001000,
- DrawFromCenter = 0x00002000,
- ScaleFromCenter = 0x00004000,
- AngleSnapFromLastPoint = 0x00008000,
- RotateShape = 0x00010000,
+ IntersectSelection = 0x00000080,
+ AutoSelectLayer = 0x00000100,
+ LeftMouseButton = 0x00000200,
+ RightMouseButton = 0x00000400,
+ StraightLineFromLastPoint = 0x00000800,
+ MoveOrigin = 0x00001000,
+ SquareAspect = 0x00002000,
+ DrawFromCenter = 0x00004000,
+ ScaleFromCenter = 0x00008000,
+ AngleSnapFromLastPoint = 0x00010000,
+ RotateShape = 0x00020000,
};
enum class WheelAction {
diff --git a/src/app/ui/keyboard_shortcuts.cpp b/src/app/ui/keyboard_shortcuts.cpp
index d324c6e22..3e46e828d 100644
--- a/src/app/ui/keyboard_shortcuts.cpp
+++ b/src/app/ui/keyboard_shortcuts.cpp
@@ -1,4 +1,5 @@
// Aseprite
+// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@@ -47,6 +48,7 @@ namespace {
{ "LockAxis" , "Lock Axis" , app::KeyAction::LockAxis },
{ "AddSelection" , "Add Selection" , app::KeyAction::AddSelection },
{ "SubtractSelection" , "Subtract Selection" , app::KeyAction::SubtractSelection },
+ { "IntersectSelection" , "Intersect Selection" , app::KeyAction::IntersectSelection },
{ "AutoSelectLayer" , "Auto Select Layer" , app::KeyAction::AutoSelectLayer },
{ "StraightLineFromLastPoint", "Straight Line from Last Point", app::KeyAction::StraightLineFromLastPoint },
{ "AngleSnapFromLastPoint", "Angle Snap from Last Point", app::KeyAction::AngleSnapFromLastPoint },
@@ -209,6 +211,7 @@ Key::Key(KeyAction action)
break;
case KeyAction::AddSelection:
case KeyAction::SubtractSelection:
+ case KeyAction::IntersectSelection:
m_keycontext = KeyContext::SelectionTool;
break;
case KeyAction::AutoSelectLayer: