Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit d78edfd4 authored by Michael Abrahams's avatar Michael Abrahams

Configure shift key = snap to axis in all tools

Summary:
Affects move tool, path manipulation tool, shape tool & assistant tool.

Also add "alt" in the move tool for precision move.

BUG: 332526

Reviewers: #krita:_next

Differential Revision: https://phabricator.kde.org/D2004
parent ed52ec59
......@@ -27,6 +27,7 @@
#include "KoPathToolSelection.h"
#include "KoSnapGuide.h"
#include "KoCanvasBase.h"
#include "kis_global.h"
KoPathPointMoveStrategy::KoPathPointMoveStrategy(KoPathTool *tool, const QPointF &pos)
: KoInteractionStrategy(*(new KoInteractionStrategyPrivate(tool))),
......@@ -46,11 +47,9 @@ void KoPathPointMoveStrategy::handleMouseMove(const QPointF &mouseLocation, Qt::
m_tool->canvas()->updateCanvas(m_tool->canvas()->snapGuide()->boundingRect());
QPointF move = newPosition - m_originalPosition;
if (modifiers & Qt::ControlModifier) { // limit change to one direction only.
if (qAbs(move.x()) > qAbs(move.y()))
move.setY(0);
else
move.setX(0);
if (modifiers & Qt::ShiftModifier) {
// Limit change to one direction only
move = snapToClosestAxis(move);
}
KoPathToolSelection * selection = dynamic_cast<KoPathToolSelection*>(m_tool->selection());
......
......@@ -248,7 +248,6 @@ void KoPathTool::insertPoints()
void KoPathTool::removePoints()
{
Q_D(KoToolBase);
// TODO finish current action or should this not possible during actions???
if (m_pointSelection.size() > 0) {
KUndo2Command *cmd = KoPathPointRemoveCommand::createCommand(m_pointSelection.selectedPointsData(), d->canvas->shapeController());
PointHandle *pointHandle = dynamic_cast<PointHandle*>(m_activeHandle);
......@@ -419,7 +418,7 @@ void KoPathTool::paint(QPainter &painter, const KoViewConverter &converter)
Q_D(KoToolBase);
painter.setRenderHint(QPainter::Antialiasing, true);
// use different colors so that it is also visible on a background of the same color
painter.setBrush(Qt::white); //TODO make configurable
painter.setBrush(Qt::white);
painter.setPen(Qt::blue);
Q_FOREACH (KoPathShape *shape, m_pointSelection.selectedShapes()) {
......@@ -442,12 +441,12 @@ void KoPathTool::paint(QPainter &painter, const KoViewConverter &converter)
painter.restore();
}
painter.setBrush(Qt::green); // TODO make color configurable
painter.setBrush(Qt::green);
painter.setPen(Qt::blue);
m_pointSelection.paint(painter, converter);
painter.setBrush(Qt::red); // TODO make color configurable
painter.setBrush(Qt::red);
painter.setPen(Qt::blue);
if (m_activeHandle) {
......@@ -770,7 +769,6 @@ void KoPathTool::mouseDoubleClickEvent(KoPointerEvent *event)
KoPathTool::PathSegment* KoPathTool::segmentAtPoint(const QPointF &point)
{
Q_D(KoToolBase);
// TODO: use global click proximity once added to the canvas resource provider
const int clickProximity = 5;
// convert click proximity to point using the current zoom level
......
......@@ -37,7 +37,8 @@ class KoParameterShape;
class QAction;
/// The tool for editing a KoPathShape or a KoParameterShape
/// The tool for editing a KoPathShape or a KoParameterShape.
/// See KoCreatePathTool for code handling the initial path creation.
class KRITAFLAKE_EXPORT KoPathTool : public KoToolBase
{
Q_OBJECT
......
......@@ -141,6 +141,16 @@ inline qreal incrementInDirection(qreal a, qreal inc, qreal direction) {
return d1 < d2 ? b1 : b2;
}
template<typename PointType>
inline PointType snapToClosestAxis(PointType P) {
if (qAbs(P.x()) < qAbs(P.y())) {
P.setX(0);
} else {
P.setY(0);
}
return P;
}
template<typename T>
inline T pow2(const T& x) {
return x * x;
......
......@@ -170,12 +170,14 @@ public:
Alternate_NONE = 10000
};
// Technically users are allowed to configure this, but nobody ever would do that.
// So these can basically be thought of as aliases to ctrl+click, etc.
enum AlternateAction {
ChangeSize = AlternateChangeSize,
PickFgNode = AlternatePickFgNode,
PickBgNode = AlternatePickBgNode,
PickFgImage = AlternatePickFgImage,
PickBgImage = AlternatePickBgImage,
ChangeSize = AlternateChangeSize, // Default: Shift+Left click
PickFgNode = AlternatePickFgNode, // Default: Ctrl+Alt+Left click
PickBgNode = AlternatePickBgNode, // Default: Ctrl+Alt+Right click
PickFgImage = AlternatePickFgImage, // Default: Ctrl+Left click
PickBgImage = AlternatePickBgImage, // Default: Ctrl+Right click
Secondary = AlternateSecondary,
Third = AlternateThird,
Fourth = AlternateFourth,
......
......@@ -233,10 +233,11 @@ void KisRulerAssistantTool::beginPrimaryAction(KoPointerEvent *event)
return;
}
m_snapIsRadial = false;
} else if (m_handleDrag && assistant->handles().size()>1 && (assistant->id() == "ruler" ||
assistant->id() == "parallel ruler" ||
assistant->id() == "infinite ruler" ||
assistant->id() == "spline")){
}
else if (m_handleDrag && assistant->handles().size()>1 && (assistant->id() == "ruler" ||
assistant->id() == "parallel ruler" ||
assistant->id() == "infinite ruler" ||
assistant->id() == "spline")){
if (m_handleDrag == assistant->handles()[0]) {
m_dragStart = *assistant->handles()[1];
} else if (m_handleDrag == assistant->handles()[1]) {
......@@ -300,7 +301,8 @@ void KisRulerAssistantTool::beginPrimaryAction(KoPointerEvent *event)
if (moveRect.contains(mousePos)) {
m_assistantDrag = assistant;
m_mousePosition = event->point;
m_cursorStart = event->point;
m_currentAdjustment = QPointF();
m_internalMode = MODE_EDITING;
return;
}
......@@ -359,7 +361,8 @@ void KisRulerAssistantTool::continuePrimaryAction(KoPointerEvent *event)
dragRadius.setLength(m_radius.length());
*m_handleDrag = dragRadius.p2();
} else if (event->modifiers() == Qt::ShiftModifier ) {
*m_handleDrag = straightLine(event->point, m_dragStart);
QPointF move = snapToClosestAxis(event->point - m_dragStart);
*m_handleDrag = m_dragStart + move;
} else {
*m_handleDrag = snapToGuide(event, QPointF(), false);
}
......@@ -380,18 +383,19 @@ void KisRulerAssistantTool::continuePrimaryAction(KoPointerEvent *event)
}
m_canvas->updateCanvas();
} else if (m_assistantDrag) {
QPointF adjust = snapToGuide(event, QPointF(), false) - m_mousePosition;
QPointF newAdjustment = snapToGuide(event, QPointF(), false) - m_cursorStart;
if (event->modifiers() == Qt::ShiftModifier ) {
newAdjustment = snapToClosestAxis(newAdjustment);
}
Q_FOREACH (KisPaintingAssistantHandleSP handle, m_assistantDrag->handles()) {
*handle += adjust;
*handle += (newAdjustment - m_currentAdjustment);
}
if (m_assistantDrag->id()== "vanishing point"){
Q_FOREACH (KisPaintingAssistantHandleSP handle, m_assistantDrag->sideHandles()) {
*handle += adjust;
*handle += (newAdjustment - m_currentAdjustment);
}
}
m_mousePosition = snapToGuide(event, QPointF(), false);
m_currentAdjustment = newAdjustment;
m_canvas->updateCanvas();
} else {
......@@ -570,22 +574,6 @@ void KisRulerAssistantTool::mouseMoveEvent(KoPointerEvent *event)
}
}
QPointF KisRulerAssistantTool::straightLine(QPointF point, QPointF compare)
{
QPointF comparison = point - compare;
QPointF result;
if (fabs(comparison.x()) > fabs(comparison.y())) {
result.setX(point.x());
result.setY(compare.y());
} else {
result.setX(compare.x());
result.setY(point.y());
}
return result;
}
void KisRulerAssistantTool::paint(QPainter& _gc, const KoViewConverter &_converter)
{
......
......@@ -59,7 +59,6 @@ private:
void outlineOn(KisPaintingAssistantSP assistant);
void outlineOff(KisPaintingAssistantSP assistant);
bool mouseNear(const QPointF& mousep, const QPointF& point);
QPointF straightLine(QPointF point, QPointF compare);
KisPaintingAssistantHandleSP nodeNearPoint(KisPaintingAssistantSP grid, QPointF point);
QPointF snapToGuide(KoPointerEvent *e, const QPointF &offset, bool useModifiers);
QPointF snapToGuide(const QPointF& pt, const QPointF &offset);
......@@ -84,7 +83,8 @@ protected:
KisPaintingAssistantHandleSP m_handleCombine;
KisPaintingAssistantSP m_assistantDrag;
KisPaintingAssistantSP m_newAssistant;
QPointF m_mousePosition;
QPointF m_cursorStart;
QPointF m_currentAdjustment;
Ui::AssistantsToolOptions m_options;
QWidget* m_optionsWidget;
QPointF m_dragStart;
......
......@@ -240,39 +240,32 @@ void KisToolMove::endPrimaryAction(KoPointerEvent *event)
void KisToolMove::beginAlternateAction(KoPointerEvent *event, AlternateAction action)
{
if (action == PickFgNode) {
// Ctrl+Right click toggles between moving current layer and moving layer w/ content
if (action == PickFgNode || action == PickBgImage) {
MoveToolMode mode = moveToolMode();
if (mode == MoveSelectedLayer || mode == MoveGroup) {
if (mode == MoveSelectedLayer) {
mode = MoveFirstLayer;
} else if (mode == MoveFirstLayer) {
mode = MoveSelectedLayer;
}
startAction(event, mode);
} else if (action == PickFgImage) {
startAction(event, MoveGroup);
} else {
KisTool::beginAlternateAction(event, action);
startAction(event, MoveGroup);
}
}
void KisToolMove::continueAlternateAction(KoPointerEvent *event, AlternateAction action)
{
if (action == PickFgNode || action == PickFgImage) {
continueAction(event);
} else {
KisTool::continueAlternateAction(event, action);
}
Q_UNUSED(action)
continueAction(event);
}
void KisToolMove::endAlternateAction(KoPointerEvent *event, AlternateAction action)
{
if (action == PickFgNode || action == PickFgImage) {
endAction(event);
} else {
KisTool::endAlternateAction(event, action);
}
Q_UNUSED(action)
endAction(event);
}
void KisToolMove::startAction(KoPointerEvent *event, MoveToolMode mode)
......@@ -378,13 +371,18 @@ bool KisToolMove::moveInProgress() const
QPoint KisToolMove::applyModifiers(Qt::KeyboardModifiers modifiers, QPoint pos)
{
QPoint adjustedPos = pos;
if (modifiers & Qt::AltModifier || modifiers & Qt::ControlModifier) {
QPoint move = pos - m_dragStart;
if (qAbs(pos.x() - m_dragStart.x()) > qAbs(pos.y() - m_dragStart.y()))
adjustedPos.setY(m_dragStart.y());
else
adjustedPos.setX(m_dragStart.x());
// Snap to axis
if (modifiers & Qt::ShiftModifier) {
move = snapToClosestAxis(move);
}
return adjustedPos;
// "Precision mode" - scale down movement by 1/5
if (modifiers & Qt::AltModifier) {
const qreal SCALE_FACTOR = .2;
move = SCALE_FACTOR * move;
}
return m_dragStart + move;
}
......@@ -109,8 +109,8 @@ private:
MoveToolOptionsWidget* m_optionsWidget;
QPoint m_dragStart;
QPoint m_accumulatedOffset;
QPoint m_dragStart; ///< Point where current cursor dragging began
QPoint m_accumulatedOffset; ///< Total offset including multiple clicks, up/down/left/right keys, etc. added together
KisStrokeId m_strokeId;
......
......@@ -32,6 +32,7 @@
#include <KoToolBase.h>
#include <KoSelection.h>
#include <klocalizedstring.h>
#include <kis_global.h>
ShapeMoveStrategy::ShapeMoveStrategy(KoToolBase *tool, const QPointF &clicked)
: KoInteractionStrategy(tool)
......@@ -64,13 +65,9 @@ void ShapeMoveStrategy::handleMouseMove(const QPointF &point, Qt::KeyboardModifi
}
QPointF diff = point - m_start;
if (modifiers & (Qt::AltModifier | Qt::ControlModifier)) {
// keep x or y position unchanged
if (qAbs(diff.x()) < qAbs(diff.y())) {
diff.setX(0);
} else {
diff.setY(0);
}
if (modifiers & Qt::ShiftModifier) {
// Limit change to one direction only
diff = snapToClosestAxis(diff);
} else {
QPointF positionToSnap = point + m_initialOffset;
tool()->canvas()->updateCanvas(tool()->canvas()->snapGuide()->boundingRect());
......@@ -88,13 +85,9 @@ void ShapeMoveStrategy::handleCustomEvent(KoPointerEvent *event)
{
QPointF diff = tool()->canvas()->viewConverter()->viewToDocument(event->pos());
if (event->modifiers() & (Qt::AltModifier | Qt::ControlModifier)) {
// keep x or y position unchanged
if (qAbs(diff.x()) < qAbs(diff.y())) {
diff.setX(0);
} else {
diff.setY(0);
}
if (event->modifiers() & Qt::ShiftModifier) {
// Limit change to one direction only
diff = snapToClosestAxis(diff);
}
m_diff += 0.1 * diff;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment