mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-04 15:40:10 +00:00
Add customization for square aspect, draw from center, and move origin keys (fix #1028)
Some changes: - Now ui::Keys aren't processed in app::tools side, they are processed in Editor side and converted to ToolLoopModifiers flags. - Replace ToolLoop::getSelectionMode -> ToolLoop::getModifiers()
This commit is contained in:
parent
5847624d0e
commit
2ce09c53dd
@ -483,6 +483,13 @@
|
||||
<!-- Modifiers for freehand tool controller -->
|
||||
<key action="StraightLineFromLastPoint" shortcut="Shift" />
|
||||
|
||||
<!-- Modifiers for two-points tool controller -->
|
||||
<key action="SquareAspect" shortcut="Shift" />
|
||||
<key action="DrawFromCenter" shortcut="Ctrl" />
|
||||
|
||||
<!-- Modifiers for two-or-more-points tools -->
|
||||
<key action="MoveOrigin" shortcut="Space" />
|
||||
|
||||
<!-- Without default shortcuts -->
|
||||
<key action="LeftMouseButton" />
|
||||
<key action="RightMouseButton" />
|
||||
|
@ -52,6 +52,11 @@
|
||||
<value id="ALL_LAYERS" value="0" />
|
||||
<value id="CURRENT_LAYER" value="1" />
|
||||
</enum>
|
||||
<enum id="SelectionMode">
|
||||
<value id="DEFAULT" value="0" />
|
||||
<value id="ADD" value="1" />
|
||||
! <value id="SUBTRACT" value="2" />
|
||||
</enum>
|
||||
<enum id="PivotPosition">
|
||||
<value id="NORTHWEST" value="0" />
|
||||
<value id="NORTH" value="1" />
|
||||
@ -151,7 +156,7 @@
|
||||
<option id="pixel_perfect" type="bool" default="false" />
|
||||
</section>
|
||||
<section id="selection">
|
||||
<option id="mode" type="app::tools::SelectionMode" default="app::tools::SelectionMode::DEFAULT" />
|
||||
<option id="mode" type="SelectionMode" default="SelectionMode::DEFAULT" />
|
||||
<option id="pivot_visibility" type="bool" default="false" />
|
||||
<option id="pivot_position" type="PivotPosition" default="PivotPosition::CENTER" />
|
||||
<option id="opaque" type="bool" default="false" />
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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> 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;
|
||||
|
@ -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"
|
||||
|
@ -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 <string>
|
||||
#include <vector>
|
||||
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 <vector>
|
||||
|
||||
@ -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);
|
||||
|
28
src/app/tools/tool_loop_modifiers.h
Normal file
28
src/app/tools/tool_loop_modifiers.h
Normal file
@ -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
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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<DrawingState*>(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);
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user