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: