[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [krita/kazakov/svg-loading] /: Implement basic strategies for editing the Gradient handles
From: Dmitry Kazakov <null () kde ! org>
Date: 2017-02-06 10:23:07
Message-ID: E1cagRv-0000uv-Ue () code ! kde ! org
[Download RAW message or body]
Git commit daa32b7a8083f896b11a18313c2052c39be4c2a5 by Dmitry Kazakov.
Committed on 06/02/2017 at 08:59.
Pushed by dkazakov into branch 'kazakov/svg-loading'.
Implement basic strategies for editing the Gradient handles
Now we also have an abstract KoInteractionStrategyFactory which
can be added/removed from the Interaction tool and therefore activate/
deactivate some user interaction.
M +1 -0 libs/flake/CMakeLists.txt
M +1 -0 libs/flake/KoGradientBackground.cpp
A +54 -0 libs/flake/tools/KoInteractionStrategyFactory.cpp [License: GPL \
(v2+)] A +58 -0 libs/flake/tools/KoInteractionStrategyFactory.h [License: \
GPL (v2+)] M +90 -3 libs/flake/tools/KoInteractionTool.cpp
M +8 -0 libs/flake/tools/KoInteractionTool.h
M +2 -0 libs/flake/tools/KoInteractionTool_p.h
M +77 -0 libs/global/KisHandlePainterHelper.cpp
M +23 -1 libs/global/KisHandlePainterHelper.h
M +1 -0 libs/ui/CMakeLists.txt
A +69 -0 libs/ui/canvas/KisSnapPointStrategy.cpp [License: GPL (v2+)]
A +50 -0 libs/ui/canvas/KisSnapPointStrategy.h [License: GPL (v2+)]
M +2 -0 plugins/tools/defaulttool/CMakeLists.txt
M +95 -15 plugins/tools/defaulttool/defaulttool/DefaultTool.cpp
M +4 -1 plugins/tools/defaulttool/defaulttool/DefaultTool.h
A +186 -0 plugins/tools/defaulttool/defaulttool/KoShapeGradientHandles.cpp \
[License: GPL (v2+)] A +68 -0 \
plugins/tools/defaulttool/defaulttool/KoShapeGradientHandles.h [License: GPL \
(v2+)] M +36 -0 plugins/tools/defaulttool/defaulttool/SelectionDecorator.cpp
A +106 -0 plugins/tools/defaulttool/defaulttool/ShapeGradientEditStrategy.cpp \
[License: GPL (v2+)] A +44 -0 \
plugins/tools/defaulttool/defaulttool/ShapeGradientEditStrategy.h [License: GPL \
(v2+)] M +0 -4 plugins/tools/defaulttool/defaulttool/ShapeMoveStrategy.cpp
M +4 -4 plugins/tools/defaulttool/defaulttool/ShapeMoveStrategy.h
M +0 -4 plugins/tools/defaulttool/defaulttool/ShapeResizeStrategy.cpp
M +0 -5 plugins/tools/defaulttool/defaulttool/ShapeRotateStrategy.cpp
M +0 -4 plugins/tools/defaulttool/defaulttool/ShapeShearStrategy.cpp
https://commits.kde.org/krita/daa32b7a8083f896b11a18313c2052c39be4c2a5
diff --git a/libs/flake/CMakeLists.txt b/libs/flake/CMakeLists.txt
index f15c3f3c6a5..ef8d49d509b 100644
--- a/libs/flake/CMakeLists.txt
+++ b/libs/flake/CMakeLists.txt
@@ -179,6 +179,7 @@ set(kritaflake_SRCS
tools/KoPanToolFactory.cpp
tools/KoInteractionTool.cpp
tools/KoInteractionStrategy.cpp
+ tools/KoInteractionStrategyFactory.cpp
tools/KoCreateShapesTool.cpp
tools/KoCreateShapesToolFactory.cpp
tools/KoShapeRubberSelectStrategy.cpp
diff --git a/libs/flake/KoGradientBackground.cpp \
b/libs/flake/KoGradientBackground.cpp index 01f8aaf5edb..e6bbce34251 100644
--- a/libs/flake/KoGradientBackground.cpp
+++ b/libs/flake/KoGradientBackground.cpp
@@ -128,6 +128,7 @@ void KoGradientBackground::paint(QPainter &painter, const \
KoViewConverter &/*con
QTransform gradientToUser(boundingRect.width(), 0, 0, boundingRect.height(),
boundingRect.x(), boundingRect.y());
+ // TODO: how about slicing the object?
QGradient g = *d->gradient;
g.setCoordinateMode(QGradient::LogicalMode);
diff --git a/libs/flake/tools/KoInteractionStrategyFactory.cpp \
b/libs/flake/tools/KoInteractionStrategyFactory.cpp new file mode 100644
index 00000000000..d01d1f1e7bc
--- /dev/null
+++ b/libs/flake/tools/KoInteractionStrategyFactory.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017 Dmitry Kazakov <dimula73@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "KoInteractionStrategyFactory.h"
+
+#include <QString>
+
+struct KoInteractionStrategyFactory::Private
+{
+ int priority = 0;
+ QString id;
+};
+
+KoInteractionStrategyFactory::KoInteractionStrategyFactory(int priority, const \
QString &id) + : m_d(new Private)
+{
+ m_d->priority = priority;
+ m_d->id = id;
+}
+
+KoInteractionStrategyFactory::~KoInteractionStrategyFactory()
+{
+}
+
+QString KoInteractionStrategyFactory::id() const
+{
+ return m_d->id;
+}
+
+int KoInteractionStrategyFactory::priority() const
+{
+ return m_d->priority;
+}
+
+bool KoInteractionStrategyFactory::compareLess(KoInteractionStrategyFactorySP f1, \
KoInteractionStrategyFactorySP f2) +{
+ return f1->priority() < f2->priority();
+}
+
diff --git a/libs/flake/tools/KoInteractionStrategyFactory.h \
b/libs/flake/tools/KoInteractionStrategyFactory.h new file mode 100644
index 00000000000..627e05daed8
--- /dev/null
+++ b/libs/flake/tools/KoInteractionStrategyFactory.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017 Dmitry Kazakov <dimula73@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KOINTERACTIONSTRATEGYFACTORY_H
+#define KOINTERACTIONSTRATEGYFACTORY_H
+
+#include <QScopedPointer>
+#include <QSharedPointer>
+#include "kritaflake_export.h"
+
+class QString;
+class QPainter;
+class KoInteractionStrategy;
+class KoPointerEvent;
+class KoViewConverter;
+
+class KoInteractionStrategyFactory;
+typedef QSharedPointer<KoInteractionStrategyFactory> KoInteractionStrategyFactorySP;
+
+class KRITAFLAKE_EXPORT KoInteractionStrategyFactory
+{
+public:
+ KoInteractionStrategyFactory(int priority, const QString &id);
+ virtual ~KoInteractionStrategyFactory();
+
+ QString id() const;
+ int priority() const;
+
+ virtual KoInteractionStrategy* createStrategy(KoPointerEvent *ev) = 0;
+ virtual bool hoverEvent(KoPointerEvent *ev) = 0;
+ virtual bool paintOnHover(QPainter &painter, const KoViewConverter &converter) = \
0; + virtual bool tryUseCustomCursor() = 0;
+
+ static bool compareLess(KoInteractionStrategyFactorySP f1, \
KoInteractionStrategyFactorySP f2); +
+private:
+ struct Private;
+ QScopedPointer<Private> m_d;
+};
+
+
+
+#endif // KOINTERACTIONSTRATEGYFACTORY_H
diff --git a/libs/flake/tools/KoInteractionTool.cpp \
b/libs/flake/tools/KoInteractionTool.cpp index dd624b75f6f..f0a89594c45 100644
--- a/libs/flake/tools/KoInteractionTool.cpp
+++ b/libs/flake/tools/KoInteractionTool.cpp
@@ -25,6 +25,10 @@
#include "KoCanvasBase.h"
#include "KoPanTool.h"
+#include "kis_global.h"
+#include "kis_assert.h"
+
+
KoInteractionTool::KoInteractionTool(KoCanvasBase *canvas)
: KoToolBase(*(new KoInteractionToolPrivate(this, canvas)))
{
@@ -37,8 +41,15 @@ KoInteractionTool::~KoInteractionTool()
void KoInteractionTool::paint(QPainter &painter, const KoViewConverter &converter)
{
Q_D(KoInteractionTool);
- if (d->currentStrategy)
+
+ if (d->currentStrategy) {
d->currentStrategy->paint(painter, converter);
+ } else {
+ Q_FOREACH (KoInteractionStrategyFactorySP factory, d->interactionFactories) \
{ + // skip the rest of rendering if the factory asks for it
+ if (factory->paintOnHover(painter, converter)) break;
+ }
+ }
}
void KoInteractionTool::mousePressEvent(KoPointerEvent *event)
@@ -48,7 +59,7 @@ void KoInteractionTool::mousePressEvent(KoPointerEvent *event)
cancelCurrentStrategy();
return;
}
- d->currentStrategy = createStrategy(event);
+ d->currentStrategy = createStrategyBase(event);
if (d->currentStrategy == 0)
event->ignore();
}
@@ -57,10 +68,17 @@ void KoInteractionTool::mouseMoveEvent(KoPointerEvent *event)
{
Q_D(KoInteractionTool);
d->lastPoint = event->point;
+
if (d->currentStrategy)
d->currentStrategy->handleMouseMove(d->lastPoint, event->modifiers());
- else
+ else {
+ Q_FOREACH (KoInteractionStrategyFactorySP factory, d->interactionFactories) \
{ + // skip the rest of rendering if the factory asks for it
+ if (factory->hoverEvent(event)) return;
+ }
+
event->ignore();
+ }
}
void KoInteractionTool::mouseReleaseEvent(KoPointerEvent *event)
@@ -123,6 +141,75 @@ void KoInteractionTool::cancelCurrentStrategy()
}
}
+KoInteractionStrategy *KoInteractionTool::createStrategyBase(KoPointerEvent *event)
+{
+ Q_D(KoInteractionTool);
+
+ Q_FOREACH (KoInteractionStrategyFactorySP factory, d->interactionFactories) {
+ KoInteractionStrategy *strategy = factory->createStrategy(event);
+ if (strategy) {
+ return strategy;
+ }
+ }
+
+ return createStrategy(event);
+}
+
+void KoInteractionTool::addInteractionFactory(KoInteractionStrategyFactory *factory)
+{
+ Q_D(KoInteractionTool);
+
+ Q_FOREACH (auto f, d->interactionFactories) {
+ KIS_SAFE_ASSERT_RECOVER_RETURN(f->id() != factory->id());
+ }
+
+ d->interactionFactories.append(toQShared(factory));
+ qSort(d->interactionFactories.begin(),
+ d->interactionFactories.end(),
+ KoInteractionStrategyFactory::compareLess);
+}
+
+void KoInteractionTool::removeInteractionFactory(const QString &id)
+{
+ Q_D(KoInteractionTool);
+ QList<KoInteractionStrategyFactorySP>::iterator it =
+ d->interactionFactories.begin();
+
+ while (it != d->interactionFactories.end()) {
+ if ((*it)->id() == id) {
+ it = d->interactionFactories.erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
+bool KoInteractionTool::hasInteractioFactory(const QString &id)
+{
+ Q_D(KoInteractionTool);
+
+ Q_FOREACH (auto f, d->interactionFactories) {
+ if (f->id() == id) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool KoInteractionTool::tryUseCustomCursor()
+{
+ Q_D(KoInteractionTool);
+
+ Q_FOREACH (auto f, d->interactionFactories) {
+ if (f->tryUseCustomCursor()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
KoInteractionTool::KoInteractionTool(KoInteractionToolPrivate &dd)
: KoToolBase(dd)
{
diff --git a/libs/flake/tools/KoInteractionTool.h \
b/libs/flake/tools/KoInteractionTool.h index 4afc29985ca..a028a6bc4ac 100644
--- a/libs/flake/tools/KoInteractionTool.h
+++ b/libs/flake/tools/KoInteractionTool.h
@@ -26,6 +26,7 @@
#include "kritaflake_export.h"
class KoInteractionStrategy;
+class KoInteractionStrategyFactory;
class KoInteractionToolPrivate;
#define KoInteractionTool_ID "InteractionTool"
@@ -86,8 +87,15 @@ protected:
* Reimplement this factory method to create your strategy to be used for mouse \
interaction.
* @returns a new strategy, or 0 when there is nothing to do.
*/
+ KoInteractionStrategy *createStrategyBase(KoPointerEvent *event);
virtual KoInteractionStrategy *createStrategy(KoPointerEvent *event) = 0;
+ void addInteractionFactory(KoInteractionStrategyFactory *factory);
+ void removeInteractionFactory(const QString &id);
+ bool hasInteractioFactory(const QString &id);
+
+ bool tryUseCustomCursor();
+
private:
KoInteractionTool(const KoInteractionTool&);
KoInteractionTool& operator=(const KoInteractionTool&);
diff --git a/libs/flake/tools/KoInteractionTool_p.h \
b/libs/flake/tools/KoInteractionTool_p.h index 069f24d6bcd..af55eef98d5 100644
--- a/libs/flake/tools/KoInteractionTool_p.h
+++ b/libs/flake/tools/KoInteractionTool_p.h
@@ -23,6 +23,7 @@
#include "KoToolBase_p.h"
#include "KoInteractionStrategy.h"
+#include "KoInteractionStrategyFactory.h"
class KoInteractionToolPrivate : public KoToolBasePrivate
{
@@ -39,6 +40,7 @@ public:
QPointF lastPoint;
KoInteractionStrategy *currentStrategy;
+ QList<QSharedPointer<KoInteractionStrategyFactory>> interactionFactories;
};
#endif
diff --git a/libs/global/KisHandlePainterHelper.cpp \
b/libs/global/KisHandlePainterHelper.cpp index 32d1891bb56..e434087ac0f 100644
--- a/libs/global/KisHandlePainterHelper.cpp
+++ b/libs/global/KisHandlePainterHelper.cpp
@@ -19,6 +19,7 @@
#include "KisHandlePainterHelper.h"
#include <QPainter>
+#include "kis_algebra_2d.h"
KisHandlePainterHelper::KisHandlePainterHelper(QPainter *_painter, qreal \
handleRadius) @@ -50,6 +51,82 @@ void KisHandlePainterHelper::drawHandleRect(const \
QPointF ¢er) {
m_painter->drawPolygon(m_handlePolygon.translated(m_painterTransform.map(center)));
}
+void KisHandlePainterHelper::drawGradientHandle(const QPointF ¢er, qreal radius) \
{ + QPolygonF handlePolygon;
+
+ handlePolygon << QPointF(-radius, 0);
+ handlePolygon << QPointF(0, radius);
+ handlePolygon << QPointF(radius, 0);
+ handlePolygon << QPointF(0, -radius);
+
+ handlePolygon = m_handleTransform.map(handlePolygon);
+ m_painter->drawPolygon(handlePolygon.translated(m_painterTransform.map(center)));
+}
+
+void KisHandlePainterHelper::drawGradientCrossHandle(const QPointF ¢er, qreal \
radius) { +
+ { // Draw a cross
+ QPainterPath p;
+ p.moveTo(-radius, -radius);
+ p.lineTo(radius, radius);
+ p.moveTo(radius, -radius);
+ p.lineTo(-radius, radius);
+
+ p = m_handleTransform.map(p);
+ m_painter->drawPath(p.translated(m_painterTransform.map(center)));
+ }
+
+ { // Draw a square
+ const qreal halfRadius = 0.5 * radius;
+
+ QPolygonF handlePolygon;
+ handlePolygon << QPointF(-halfRadius, 0);
+ handlePolygon << QPointF(0, halfRadius);
+ handlePolygon << QPointF(halfRadius, 0);
+ handlePolygon << QPointF(0, -halfRadius);
+
+ handlePolygon = m_handleTransform.map(handlePolygon);
+ m_painter->drawPolygon(handlePolygon.translated(m_painterTransform.map(center)));
+ }
+}
+
+void KisHandlePainterHelper::drawArrow(const QPointF &pos, const QPointF &from, \
qreal radius) +{
+ QPainterPath p;
+
+ QLineF line(pos, from);
+ line.setLength(radius);
+
+ QPointF norm = KisAlgebra2D::leftUnitNormal(pos - from);
+ norm *= 0.34 * radius;
+
+ p.moveTo(line.p2() + norm);
+ p.lineTo(line.p1());
+ p.lineTo(line.p2() - norm);
+
+ p.translate(-pos);
+
+ m_painter->drawPath(m_handleTransform.map(p).translated(m_painterTransform.map(pos)));
+}
+
+void KisHandlePainterHelper::drawGradientArrow(const QPointF &start, const QPointF \
&end, qreal radius) +{
+ QPainterPath p;
+ p.moveTo(start);
+ p.lineTo(end);
+ m_painter->drawPath(m_painterTransform.map(p));
+
+ const qreal length = kisDistance(start, end);
+ const QPointF diff = end - start;
+
+ if (length > 5 * radius) {
+ drawArrow(start + 0.33 * diff, start, radius);
+ drawArrow(start + 0.66 * diff, start, radius);
+ } else if (length > 3 * radius) {
+ drawArrow(start + 0.5 * diff, start, radius);
+ }
+}
+
void KisHandlePainterHelper::drawRubberLine(const QPolygonF &poly) {
m_painter->drawPolygon(m_painterTransform.map(poly));
}
diff --git a/libs/global/KisHandlePainterHelper.h \
b/libs/global/KisHandlePainterHelper.h index 72d940323d0..84e01be2530 100644
--- a/libs/global/KisHandlePainterHelper.h
+++ b/libs/global/KisHandlePainterHelper.h
@@ -62,17 +62,39 @@ public:
void drawHandleRect(const QPointF ¢er);
/**
+ * Draw a rotated handle representing the gradient handle
+ */
+ void drawGradientHandle(const QPointF ¢er, qreal radius);
+
+ /**
+ * Draw a special handle representing the center of the gradient
+ */
+ void drawGradientCrossHandle(const QPointF ¢er, qreal radius);
+
+ /**
+ * Draw an arrow representing gradient position
+ */
+ void drawGradientArrow(const QPointF &start, const QPointF &end, qreal radius);
+
+ /**
* Draw a line showing the bounding box of the selection
*/
void drawRubberLine(const QPolygonF &poly);
private:
+
+ /**
+ * Draw a single arrow with the tip at position \p pos, directed from \p from,
+ * of size \p radius.
+ */
+ void drawArrow(const QPointF &pos, const QPointF &from, qreal radius);
+
+private:
QPainter *m_painter;
QTransform m_painterTransform;
KisAlgebra2D::DecomposedMatix m_decomposedMatrix;
QTransform m_handleTransform;
QPolygonF m_handlePolygon;
-
};
#endif // KISHANDLEPAINTERHELPER_H
diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt
index 659ed48a7fe..f1afd3b65d0 100644
--- a/libs/ui/CMakeLists.txt
+++ b/libs/ui/CMakeLists.txt
@@ -43,6 +43,7 @@ set(kritaui_LIB_SRCS
canvas/kis_guides_config.cpp
canvas/kis_snap_config.cpp
canvas/kis_snap_line_strategy.cpp
+ canvas/KisSnapPointStrategy.cpp
dialogs/kis_about_application.cpp
dialogs/kis_dlg_adj_layer_props.cc
dialogs/kis_dlg_adjustment_layer.cc
diff --git a/libs/ui/canvas/KisSnapPointStrategy.cpp \
b/libs/ui/canvas/KisSnapPointStrategy.cpp new file mode 100644
index 00000000000..712ebbedc12
--- /dev/null
+++ b/libs/ui/canvas/KisSnapPointStrategy.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017 Dmitry Kazakov <dimula73@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "KisSnapPointStrategy.h"
+
+#include <QPainterPath>
+#include "kis_global.h"
+
+struct KisSnapPointStrategy::Private
+{
+ QList<QPointF> points;
+};
+
+KisSnapPointStrategy::KisSnapPointStrategy(KoSnapGuide::Strategy type)
+ : KoSnapStrategy(type),
+ m_d(new Private)
+{
+}
+
+KisSnapPointStrategy::~KisSnapPointStrategy()
+{
+}
+
+bool KisSnapPointStrategy::snap(const QPointF &mousePosition, KoSnapProxy *proxy, \
qreal maxSnapDistance) +{
+ Q_UNUSED(proxy);
+
+ QPointF snappedPoint = mousePosition;
+ qreal minDistance = std::numeric_limits<qreal>::max();
+
+ Q_FOREACH (const QPointF &pt, m_d->points) {
+ const qreal dist = kisDistance(mousePosition, pt);
+
+ if (dist < maxSnapDistance && dist < minDistance) {
+ minDistance = dist;
+ snappedPoint = pt;
+ }
+ }
+
+ setSnappedPosition(snappedPoint);
+ return minDistance < std::numeric_limits<qreal>::max();
+}
+
+QPainterPath KisSnapPointStrategy::decoration(const KoViewConverter &converter) \
const +{
+ Q_UNUSED(converter);
+ return QPainterPath();
+}
+
+void KisSnapPointStrategy::addPoint(const QPointF &pt)
+{
+ m_d->points << pt;
+}
+
diff --git a/libs/ui/canvas/KisSnapPointStrategy.h \
b/libs/ui/canvas/KisSnapPointStrategy.h new file mode 100644
index 00000000000..506f1da0473
--- /dev/null
+++ b/libs/ui/canvas/KisSnapPointStrategy.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017 Dmitry Kazakov <dimula73@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISSNAPPOINTSTRATEGY_H
+#define KISSNAPPOINTSTRATEGY_H
+
+#include <QScopedPointer>
+
+#include "KoSnapStrategy.h"
+#include "kritaui_export.h"
+
+/**
+ * The KisSnapPointStrategy class is a custom strategy that allows snapping to
+ * arbitrary points on canvas, not linked to any real objects. It can be used,
+ * for example, for snapping to the *previous position* of the handle, while it
+ * is dragging by the user.
+ */
+
+class KRITAUI_EXPORT KisSnapPointStrategy : public KoSnapStrategy
+{
+public:
+ KisSnapPointStrategy(KoSnapGuide::Strategy type = KoSnapGuide::CustomSnapping);
+ ~KisSnapPointStrategy();
+
+ bool snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal \
maxSnapDistance) override; + QPainterPath decoration(const KoViewConverter \
&converter) const override; +
+ void addPoint(const QPointF &pt);
+
+private:
+ struct Private;
+ const QScopedPointer<Private> m_d;
+};
+
+#endif // KISSNAPPOINTSTRATEGY_H
diff --git a/plugins/tools/defaulttool/CMakeLists.txt \
b/plugins/tools/defaulttool/CMakeLists.txt index afca8e6dbe5..c8e9cbba47b 100644
--- a/plugins/tools/defaulttool/CMakeLists.txt
+++ b/plugins/tools/defaulttool/CMakeLists.txt
@@ -10,8 +10,10 @@ set ( defaulttools_SRCS
defaulttool/ShapeResizeStrategy.cpp
defaulttool/ShapeRotateStrategy.cpp
defaulttool/ShapeShearStrategy.cpp
+ defaulttool/ShapeGradientEditStrategy.cpp
defaulttool/SelectionDecorator.cpp
defaulttool/KoFillConfigWidget.cpp
+ defaulttool/KoShapeGradientHandles.cpp
connectionTool/ConnectionTool.cpp
connectionTool/ConnectionToolFactory.cpp
diff --git a/plugins/tools/defaulttool/defaulttool/DefaultTool.cpp \
b/plugins/tools/defaulttool/defaulttool/DefaultTool.cpp index \
69751cc65dd..246113bd266 100644
--- a/plugins/tools/defaulttool/defaulttool/DefaultTool.cpp
+++ b/plugins/tools/defaulttool/defaulttool/DefaultTool.cpp
@@ -52,6 +52,7 @@
#include <KoSnapGuide.h>
#include <KoStrokeConfigWidget.h>
#include "kis_action_registry.h"
+#include <KoInteractionStrategyFactory.h>
#include <KoIcon.h>
@@ -116,10 +117,6 @@ public:
void finishInteraction(Qt::KeyboardModifiers /*modifiers*/) override {}
void paint(QPainter &painter, const KoViewConverter &converter) {
- SelectionDecorator decorator(tool()->canvas()->resourceManager());
- decorator.setSelection(tool()->canvas()->shapeManager()->selection());
- decorator.setHandleRadius(handleRadius());
- decorator.paint(painter, converter);
}
};
@@ -132,15 +129,94 @@ public:
}
void paint(QPainter &painter, const KoViewConverter &converter) {
- SelectionDecorator decorator(tool()->canvas()->resourceManager());
- decorator.setSelection(tool()->canvas()->shapeManager()->selection());
- decorator.setHandleRadius(handleRadius());
- decorator.paint(painter, converter);
-
KoShapeRubberSelectStrategy::paint(painter, converter);
}
};
+#include <KoGradientBackground.h>
+#include "KoShapeGradientHandles.h"
+#include "ShapeGradientEditStrategy.h"
+
+class DefaultTool::MoveGradientHandleInteractionFactory : public \
KoInteractionStrategyFactory +{
+public:
+ MoveGradientHandleInteractionFactory(DefaultTool *_q)
+ : KoInteractionStrategyFactory(0, "move_gradient_handle"),
+ q(_q)
+ {
+ }
+
+ KoInteractionStrategy* createStrategy(KoPointerEvent *ev) override
+ {
+ m_currentHandle = handleAt(ev->point);
+
+ if (m_currentHandle.type != KoShapeGradientHandles::Handle::None) {
+ KoShape *shape = onlyEditableShape();
+ KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(shape, 0);
+
+ return new ShapeGradientEditStrategy(q, shape, m_currentHandle.type, \
ev->point); + }
+
+ return 0;
+ }
+
+ bool hoverEvent(KoPointerEvent *ev) override
+ {
+ m_currentHandle = handleAt(ev->point);
+ return false;
+ }
+
+ bool paintOnHover(QPainter &painter, const KoViewConverter &converter) override
+ {
+ return false;
+ }
+
+ bool tryUseCustomCursor() {
+ if (m_currentHandle.type != KoShapeGradientHandles::Handle::None) {
+ q->useCursor(Qt::OpenHandCursor);
+ }
+
+ return m_currentHandle.type != KoShapeGradientHandles::Handle::None;
+ }
+
+private:
+
+ KoShape* onlyEditableShape() const {
+ KoSelection *selection = q->koSelection();
+ QList<KoShape*> shapes = selection->selectedEditableShapes();
+
+ KoShape *shape = 0;
+ if (shapes.size() == 1) {
+ shape = shapes.first();
+ }
+
+ return shape;
+ }
+
+ KoShapeGradientHandles::Handle handleAt(const QPointF &pos) {
+ KoShapeGradientHandles::Handle result;
+ KoShape *shape = onlyEditableShape();
+ if (shape) {
+ qreal minDistanceSq = std::numeric_limits<qreal>::max();
+
+ KoShapeGradientHandles sh(shape);
+ Q_FOREACH (const KoShapeGradientHandles::Handle &handle, sh.handles()) {
+ const qreal distanceSq = kisSquareDistance(handle.pos, pos);
+
+ if (distanceSq < HANDLE_DISTANCE_SQ && distanceSq < minDistanceSq) {
+ result = handle;
+ minDistanceSq = distanceSq;
+ }
+ }
+ }
+
+ return result;
+ }
+
+private:
+ DefaultTool *q;
+ KoShapeGradientHandles::Handle m_currentHandle;
+};
class SelectionHandler : public KoToolSelection
{
@@ -215,6 +291,8 @@ DefaultTool::DefaultTool(KoCanvasBase *canvas)
KoShapeManager *manager = canvas->shapeManager();
connect(manager, SIGNAL(selectionChanged()), this, SLOT(updateActions()));
+
+ addInteractionFactory(new MoveGradientHandleInteractionFactory(this));
}
DefaultTool::~DefaultTool()
@@ -402,6 +480,8 @@ qreal DefaultTool::rotationOfHandle(KoFlake::SelectionHandle \
handle, bool useEdg
void DefaultTool::updateCursor()
{
+ if (tryUseCustomCursor()) return;
+
QCursor cursor = Qt::ArrowCursor;
QString statusText;
@@ -515,13 +595,13 @@ void DefaultTool::updateCursor()
void DefaultTool::paint(QPainter &painter, const KoViewConverter &converter)
{
+ SelectionDecorator decorator(canvas()->resourceManager());
+ decorator.setSelection(koSelection());
+ decorator.setHandleRadius(handleRadius());
+ decorator.paint(painter, converter);
+
KoInteractionTool::paint(painter, converter);
- if (currentStrategy() == 0 && koSelection()->count() > 0) {
- SelectionDecorator decorator(canvas()->resourceManager());
- decorator.setSelection(koSelection());
- decorator.setHandleRadius(handleRadius());
- decorator.paint(painter, converter);
- }
+
painter.save();
KoShape::applyConversion(painter, converter);
canvas()->snapGuide()->paint(painter, converter);
diff --git a/plugins/tools/defaulttool/defaulttool/DefaultTool.h \
b/plugins/tools/defaulttool/defaulttool/DefaultTool.h index 441d838323e..e0c8a46078d \
100644
--- a/plugins/tools/defaulttool/defaulttool/DefaultTool.h
+++ b/plugins/tools/defaulttool/defaulttool/DefaultTool.h
@@ -124,7 +124,10 @@ public: // Events
protected:
QList<QPointer<QWidget> > createOptionWidgets();
- virtual KoInteractionStrategy *createStrategy(KoPointerEvent *event);
+ KoInteractionStrategy *createStrategy(KoPointerEvent *event) override;
+
+private:
+ class MoveGradientHandleInteractionFactory;
private:
void setupActions();
diff --git a/plugins/tools/defaulttool/defaulttool/KoShapeGradientHandles.cpp \
b/plugins/tools/defaulttool/defaulttool/KoShapeGradientHandles.cpp new file mode \
100644 index 00000000000..dec9f2eba51
--- /dev/null
+++ b/plugins/tools/defaulttool/defaulttool/KoShapeGradientHandles.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2017 Dmitry Kazakov <dimula73@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "KoShapeGradientHandles.h"
+
+#include <QGradient>
+#include <KoShape.h>
+#include <KoGradientBackground.h>
+#include <KoShapeBackgroundCommand.h>
+#include <kis_assert.h>
+
+KoShapeGradientHandles::KoShapeGradientHandles(KoShape *shape)
+ : m_shape(shape)
+{
+}
+
+QVector<KoShapeGradientHandles::Handle> KoShapeGradientHandles::handles(const \
KoViewConverter *converter) const { + QVector<Handle> result;
+
+ const QGradient *g = gradient();
+ if (!g) return result;
+
+ switch (g->type()) {
+ case QGradient::LinearGradient: {
+ const QLinearGradient *lgradient = static_cast<const QLinearGradient*>(g);
+ result << Handle(Handle::LinearStart, lgradient->start());
+ result << Handle(Handle::LinearEnd, lgradient->finalStop());
+ break;
+ }
+ case QGradient::RadialGradient: {
+ const QRadialGradient *rgradient = static_cast<const QRadialGradient*>(g);
+
+ result << Handle(Handle::RadialCenter, rgradient->center());
+
+ if (rgradient->center() != rgradient->focalPoint()) {
+ result << Handle(Handle::RadialFocalPoint, rgradient->focalPoint());
+ }
+
+ result << Handle(Handle::RadialRadius,
+ rgradient->center() + QPointF(rgradient->centerRadius(), \
0)); + break;
+ }
+ case QGradient::ConicalGradient:
+ // not supported
+ break;
+ case QGradient::NoGradient:
+ // not supported
+ break;
+ }
+
+ if (g->coordinateMode() == QGradient::ObjectBoundingMode) {
+ const QRectF boundingRect = m_shape->outlineRect();
+ const QTransform gradientToUser(boundingRect.width(), 0, 0, \
boundingRect.height(), + boundingRect.x(), \
boundingRect.y()); + const QTransform t = gradientToUser * \
m_shape->absoluteTransformation(converter); +
+ QVector<Handle>::iterator it = result.begin();
+
+
+
+ for (; it != result.end(); ++it) {
+ it->pos = t.map(it->pos);
+ }
+ }
+
+ return result;
+}
+
+QGradient::Type KoShapeGradientHandles::type() const
+{
+ const QGradient *g = gradient();
+ return g ? g->type() : QGradient::NoGradient;
+}
+
+KUndo2Command *KoShapeGradientHandles::moveGradientHandle(KoShapeGradientHandles::Handle::Type \
handleType, const QPointF &absoluteOffset) +{
+ KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(handleType != Handle::None, 0);
+
+ QSharedPointer<KoShapeBackground> bg = m_shape->background();
+ KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(bg, 0);
+
+ QSharedPointer<KoGradientBackground> gradientBg =
+ qSharedPointerDynamicCast<KoGradientBackground>(bg);
+ KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(gradientBg, 0);
+
+ QGradient *newGradient = 0;
+
+ switch (gradientBg->gradient()->type()) {
+ case QGradient::LinearGradient: {
+ KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(handleType == Handle::LinearStart ||
+ handleType == Handle::LinearEnd, 0);
+
+ newGradient = KoFlake::cloneGradient(gradientBg->gradient());
+ QLinearGradient *lgradient = static_cast<QLinearGradient*>(newGradient);
+
+ if (handleType == Handle::LinearStart) {
+ lgradient->setStart(getNewHandlePos(lgradient->start(), absoluteOffset, \
newGradient->coordinateMode())); + } else if (handleType == Handle::LinearEnd) \
{ + lgradient->setFinalStop(getNewHandlePos(lgradient->finalStop(), \
absoluteOffset, newGradient->coordinateMode())); +
+ }
+ break;
+ }
+ case QGradient::RadialGradient: {
+ newGradient = KoFlake::cloneGradient(gradientBg->gradient());
+ QRadialGradient *rgradient = static_cast<QRadialGradient*>(newGradient);
+
+ if (handleType == Handle::RadialCenter) {
+ rgradient->setCenter(getNewHandlePos(rgradient->center(), \
absoluteOffset, newGradient->coordinateMode())); + } else if (handleType == \
Handle::RadialFocalPoint) { + \
rgradient->setFocalPoint(getNewHandlePos(rgradient->focalPoint(), absoluteOffset, \
newGradient->coordinateMode())); + } else if (handleType == \
Handle::RadialRadius) { + QPointF radiusPos = rgradient->center() + \
QPointF(QPointF(rgradient->radius(), 0)); + radiusPos = \
getNewHandlePos(radiusPos, absoluteOffset, newGradient->coordinateMode()); + \
rgradient->setRadius(radiusPos.x() - rgradient->center().x()); + }
+ break;
+ }
+ case QGradient::ConicalGradient:
+ // not supported
+ break;
+ case QGradient::NoGradient:
+ // not supported
+ break;
+ }
+
+ QSharedPointer<KoGradientBackground> newFill(
+ new KoGradientBackground(newGradient, gradientBg->transform()));
+
+ return new KoShapeBackgroundCommand(m_shape, newFill);
+}
+
+KoShapeGradientHandles::Handle \
KoShapeGradientHandles::getHandle(KoShapeGradientHandles::Handle::Type handleType) +{
+ Handle result;
+
+ Q_FOREACH (const Handle &h, handles()) {
+ if (h.type == handleType) {
+ result = h;
+ break;
+ }
+ }
+
+ return result;
+}
+
+const QGradient *KoShapeGradientHandles::gradient() const {
+ QSharedPointer<KoShapeBackground> bg = m_shape->background();
+ if (!bg) return 0;
+
+ QSharedPointer<KoGradientBackground> gradientBg =
+ qSharedPointerDynamicCast<KoGradientBackground>(bg);
+ if (!gradientBg) return 0;
+
+ return gradientBg->gradient();
+}
+
+QPointF KoShapeGradientHandles::getNewHandlePos(const QPointF &oldPos, const QPointF \
&absoluteOffset, QGradient::CoordinateMode mode) +{
+ const QTransform offset = QTransform::fromTranslate(absoluteOffset.x(), \
absoluteOffset.y()); + QTransform localToAbsolute = \
m_shape->absoluteTransformation(0); +
+ if (mode == QGradient::ObjectBoundingMode) {
+ const QRectF boundingRect = m_shape->outlineRect();
+ const QTransform gradientToUser(boundingRect.width(), 0, 0, \
boundingRect.height(), + boundingRect.x(), \
boundingRect.y()); + localToAbsolute = gradientToUser * localToAbsolute;
+ }
+
+ return (localToAbsolute * offset * localToAbsolute.inverted()).map(oldPos);
+}
diff --git a/plugins/tools/defaulttool/defaulttool/KoShapeGradientHandles.h \
b/plugins/tools/defaulttool/defaulttool/KoShapeGradientHandles.h new file mode 100644
index 00000000000..4c248552c30
--- /dev/null
+++ b/plugins/tools/defaulttool/defaulttool/KoShapeGradientHandles.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017 Dmitry Kazakov <dimula73@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KOSHAPEGRADIENTHANDLES_H
+#define KOSHAPEGRADIENTHANDLES_H
+
+#include <QPointF>
+
+#include <QGradient>
+
+class KoShape;
+class KoViewConverter;
+class KUndo2Command;
+
+class KoShapeGradientHandles
+{
+public:
+ struct Handle {
+ enum Type {
+ None,
+ LinearStart,
+ LinearEnd,
+ RadialCenter,
+ RadialRadius,
+ RadialFocalPoint
+ };
+
+ Handle() : type(None) {}
+ Handle(Type t, const QPointF &p) : type(t), pos(p) {}
+
+ Type type;
+ QPointF pos;
+ };
+
+public:
+ KoShapeGradientHandles(KoShape *shape);
+ QVector<Handle> handles(const KoViewConverter *converter = 0) const;
+ QGradient::Type type() const;
+
+ KUndo2Command* moveGradientHandle(Handle::Type handleType, const QPointF \
&absoluteOffset); + Handle getHandle(Handle::Type handleType);
+
+
+
+private:
+ const QGradient* gradient() const;
+ QPointF getNewHandlePos(const QPointF &oldPos, const QPointF &absoluteOffset, \
QGradient::CoordinateMode mode); +
+private:
+ KoShape *m_shape;
+};
+
+#endif // KOSHAPEGRADIENTHANDLES_H
diff --git a/plugins/tools/defaulttool/defaulttool/SelectionDecorator.cpp \
b/plugins/tools/defaulttool/defaulttool/SelectionDecorator.cpp index \
1cd721933b2..ebe4e53c6df 100644
--- a/plugins/tools/defaulttool/defaulttool/SelectionDecorator.cpp
+++ b/plugins/tools/defaulttool/defaulttool/SelectionDecorator.cpp
@@ -30,6 +30,7 @@
#include <KisHandlePainterHelper.h>
#include <KoCanvasResourceManager.h>
#include <KisQPainterStateSaver.h>
+#include "KoShapeGradientHandles.h"
#define HANDLE_DISTANCE 10
@@ -124,5 +125,40 @@ void SelectionDecorator::paint(QPainter &painter, const \
KoViewConverter &convert helper.drawHandleRect(hotPos);
}
}
+
+ if (editable && selectedShapes.size() == 1) {
+ KoShape *shape = selectedShapes.first();
+
+ KoShapeGradientHandles gradientHandles(shape);
+ QVector<KoShapeGradientHandles::Handle> handles = gradientHandles.handles();
+
+ KisHandlePainterHelper helper(&painter);
+ const QTransform t = shape->absoluteTransformation(0).inverted();
+
+ painter.setPen(pen);
+ painter.setBrush(Qt::white);
+
+ if (gradientHandles.type() == QGradient::LinearGradient) {
+ KIS_SAFE_ASSERT_RECOVER_NOOP(handles.size() == 2);
+
+ if (handles.size() == 2) {
+ helper.drawGradientArrow(t.map(handles[0].pos), \
t.map(handles[1].pos), 1.5 * m_handleRadius); + }
+ }
+
+ pen.setColor(QColor(255, 197, 39));
+ painter.setPen(pen);
+ painter.setBrush(Qt::white);
+
+ Q_FOREACH (const KoShapeGradientHandles::Handle &h, handles) {
+ if (h.type == KoShapeGradientHandles::Handle::RadialCenter) {
+ helper.drawGradientCrossHandle(t.map(h.pos), 1.2 * m_handleRadius);
+ } else {
+ helper.drawGradientHandle(t.map(h.pos), 1.2 * m_handleRadius);
+ }
+ }
+
+
+ }
}
diff --git a/plugins/tools/defaulttool/defaulttool/ShapeGradientEditStrategy.cpp \
b/plugins/tools/defaulttool/defaulttool/ShapeGradientEditStrategy.cpp new file mode \
100644 index 00000000000..9c7e22219f6
--- /dev/null
+++ b/plugins/tools/defaulttool/defaulttool/ShapeGradientEditStrategy.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2017 Dmitry Kazakov <dimula73@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "ShapeGradientEditStrategy.h"
+
+#include <KoToolBase.h>
+#include <KoCanvasBase.h>
+#include <KoCanvasResourceManager.h>
+#include <KoShapeManager.h>
+#include <KoShape.h>
+#include "kis_assert.h"
+#include "SelectionDecorator.h"
+#include <kundo2command.h>
+#include <KoSnapGuide.h>
+#include <KisSnapPointStrategy.h>
+
+#include "kis_debug.h"
+
+
+struct ShapeGradientEditStrategy::Private
+{
+ Private(const QPointF &_start, KoShape *shape)
+ : start(_start),
+ gradientHandles(shape)
+ {
+ }
+
+ QPointF start;
+ QPointF initialOffset;
+ KoShapeGradientHandles gradientHandles;
+ KoShapeGradientHandles::Handle::Type handleType;
+ QScopedPointer<KUndo2Command> intermediateCommand;
+};
+
+
+ShapeGradientEditStrategy::ShapeGradientEditStrategy(KoToolBase *tool,
+ KoShape *shape,
+ \
KoShapeGradientHandles::Handle::Type startHandleType, + \
const QPointF &clicked) + : KoInteractionStrategy(tool)
+ , m_d(new Private(clicked, shape))
+{
+ KIS_SAFE_ASSERT_RECOVER_RETURN(shape);
+
+ m_d->handleType = startHandleType;
+
+ KoShapeGradientHandles::Handle handle = \
m_d->gradientHandles.getHandle(m_d->handleType); + m_d->initialOffset = handle.pos \
- clicked; +
+ KisSnapPointStrategy *strategy = new KisSnapPointStrategy();
+ Q_FOREACH (const KoShapeGradientHandles::Handle &h, \
m_d->gradientHandles.handles()) { + strategy->addPoint(h.pos);
+ }
+ tool->canvas()->snapGuide()->addCustomSnapStrategy(strategy);
+}
+
+ShapeGradientEditStrategy::~ShapeGradientEditStrategy()
+{
+}
+
+void ShapeGradientEditStrategy::handleMouseMove(const QPointF &mouseLocation, \
Qt::KeyboardModifiers modifiers) +{
+ if (m_d->intermediateCommand) {
+ m_d->intermediateCommand->undo();
+ m_d->intermediateCommand.reset();
+ }
+
+ const QPointF snappedPosition = \
tool()->canvas()->snapGuide()->snap(mouseLocation, m_d->initialOffset, modifiers); + \
const QPointF diff = snappedPosition- m_d->start; + \
m_d->intermediateCommand.reset(m_d->gradientHandles.moveGradientHandle(m_d->handleType, \
diff)); + m_d->intermediateCommand->redo();
+
+ tool()->canvas()->updateCanvas(tool()->canvas()->snapGuide()->boundingRect());
+}
+
+KUndo2Command *ShapeGradientEditStrategy::createCommand()
+{
+ return m_d->intermediateCommand.take();
+}
+
+void ShapeGradientEditStrategy::finishInteraction(Qt::KeyboardModifiers modifiers)
+{
+ const QRectF dirtyRect = tool()->canvas()->snapGuide()->boundingRect();
+ tool()->canvas()->snapGuide()->reset();
+ tool()->canvas()->updateCanvas(dirtyRect);
+}
+
+void ShapeGradientEditStrategy::paint(QPainter &painter, const KoViewConverter \
&converter) +{
+}
+
diff --git a/plugins/tools/defaulttool/defaulttool/ShapeGradientEditStrategy.h \
b/plugins/tools/defaulttool/defaulttool/ShapeGradientEditStrategy.h new file mode \
100644 index 00000000000..6a390964613
--- /dev/null
+++ b/plugins/tools/defaulttool/defaulttool/ShapeGradientEditStrategy.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017 Dmitry Kazakov <dimula73@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SHAPEGRADIENTEDITSTRATEGY_H
+#define SHAPEGRADIENTEDITSTRATEGY_H
+
+#include <QScopedPointer>
+#include <KoInteractionStrategy.h>
+#include "KoShapeGradientHandles.h"
+
+class ShapeGradientEditStrategy : public KoInteractionStrategy
+{
+public:
+ ShapeGradientEditStrategy(KoToolBase *tool, KoShape *shape,
+ KoShapeGradientHandles::Handle::Type startHandleType,
+ const QPointF &clicked);
+ ~ShapeGradientEditStrategy();
+
+ void handleMouseMove(const QPointF &mouseLocation, Qt::KeyboardModifiers \
modifiers) override; + KUndo2Command *createCommand() override;
+ void finishInteraction(Qt::KeyboardModifiers modifiers) override;
+ void paint(QPainter &painter, const KoViewConverter &converter) override;
+
+private:
+ struct Private;
+ QScopedPointer<Private> m_d;
+};
+
+#endif // SHAPEGRADIENTEDITSTRATEGY_H
diff --git a/plugins/tools/defaulttool/defaulttool/ShapeMoveStrategy.cpp \
b/plugins/tools/defaulttool/defaulttool/ShapeMoveStrategy.cpp index \
7b901b58213..fb5609d9f85 100644
--- a/plugins/tools/defaulttool/defaulttool/ShapeMoveStrategy.cpp
+++ b/plugins/tools/defaulttool/defaulttool/ShapeMoveStrategy.cpp
@@ -122,8 +122,4 @@ void ShapeMoveStrategy::finishInteraction(Qt::KeyboardModifiers \
modifiers)
void ShapeMoveStrategy::paint(QPainter &painter, const KoViewConverter &converter)
{
- SelectionDecorator decorator(tool()->canvas()->resourceManager());
- decorator.setSelection(tool()->canvas()->shapeManager()->selection());
- decorator.setHandleRadius(handleRadius());
- decorator.paint(painter, converter);
}
diff --git a/plugins/tools/defaulttool/defaulttool/ShapeMoveStrategy.h \
b/plugins/tools/defaulttool/defaulttool/ShapeMoveStrategy.h index \
e7ed5bfd14c..b509d13f97c 100644
--- a/plugins/tools/defaulttool/defaulttool/ShapeMoveStrategy.h
+++ b/plugins/tools/defaulttool/defaulttool/ShapeMoveStrategy.h
@@ -46,10 +46,10 @@ public:
ShapeMoveStrategy(KoToolBase *tool, const QPointF &clicked);
virtual ~ShapeMoveStrategy() {}
- void handleMouseMove(const QPointF &mouseLocation, Qt::KeyboardModifiers \
modifiers);
- KUndo2Command *createCommand();
- void finishInteraction(Qt::KeyboardModifiers modifiers);
- virtual void paint(QPainter &painter, const KoViewConverter &converter);
+ void handleMouseMove(const QPointF &mouseLocation, Qt::KeyboardModifiers \
modifiers) override; + KUndo2Command *createCommand() override;
+ void finishInteraction(Qt::KeyboardModifiers modifiers) override;
+ virtual void paint(QPainter &painter, const KoViewConverter &converter) \
override; private:
void moveSelection(const QPointF &diff);
QList<QPointF> m_previousPositions;
diff --git a/plugins/tools/defaulttool/defaulttool/ShapeResizeStrategy.cpp \
b/plugins/tools/defaulttool/defaulttool/ShapeResizeStrategy.cpp index \
d914cee77f8..5354935d875 100644
--- a/plugins/tools/defaulttool/defaulttool/ShapeResizeStrategy.cpp
+++ b/plugins/tools/defaulttool/defaulttool/ShapeResizeStrategy.cpp
@@ -237,8 +237,4 @@ void ShapeResizeStrategy::finishInteraction(Qt::KeyboardModifiers \
modifiers)
void ShapeResizeStrategy::paint(QPainter &painter, const KoViewConverter &converter)
{
- SelectionDecorator decorator(tool()->canvas()->resourceManager());
- decorator.setSelection(tool()->canvas()->shapeManager()->selection());
- decorator.setHandleRadius(handleRadius());
- decorator.paint(painter, converter);
}
diff --git a/plugins/tools/defaulttool/defaulttool/ShapeRotateStrategy.cpp \
b/plugins/tools/defaulttool/defaulttool/ShapeRotateStrategy.cpp index \
05ad433fa00..1dfa225bb3b 100644
--- a/plugins/tools/defaulttool/defaulttool/ShapeRotateStrategy.cpp
+++ b/plugins/tools/defaulttool/defaulttool/ShapeRotateStrategy.cpp
@@ -89,11 +89,6 @@ void ShapeRotateStrategy::rotateBy(qreal angle)
void ShapeRotateStrategy::paint(QPainter &painter, const KoViewConverter &converter)
{
- SelectionDecorator decorator(tool()->canvas()->resourceManager());
- decorator.setSelection(tool()->canvas()->shapeManager()->selection());
- decorator.setHandleRadius(handleRadius());
- decorator.paint(painter, converter);
-
// paint the rotation center
painter.setPen(QPen(Qt::red));
painter.setBrush(QBrush(Qt::red));
diff --git a/plugins/tools/defaulttool/defaulttool/ShapeShearStrategy.cpp \
b/plugins/tools/defaulttool/defaulttool/ShapeShearStrategy.cpp index \
74412c2473d..29fd6a45113 100644
--- a/plugins/tools/defaulttool/defaulttool/ShapeShearStrategy.cpp
+++ b/plugins/tools/defaulttool/defaulttool/ShapeShearStrategy.cpp
@@ -155,10 +155,6 @@ void ShapeShearStrategy::handleMouseMove(const QPointF &point, \
Qt::KeyboardModif
void ShapeShearStrategy::paint(QPainter &painter, const KoViewConverter &converter)
{
- SelectionDecorator decorator(tool()->canvas()->resourceManager());
- decorator.setSelection(tool()->canvas()->shapeManager()->selection());
- decorator.setHandleRadius(handleRadius());
- decorator.paint(painter, converter);
}
KUndo2Command *ShapeShearStrategy::createCommand()
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic