1 /* This file is part of the KDE project
2  * Copyright (C) 2008-2009 Jan Hambrecht <jaham@gmx.net>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 #ifndef KOSNAPSTRATEGY_H
21 #define KOSNAPSTRATEGY_H
22 
23 #include "KoSnapGuide.h"
24 
25 #include <QLineF>
26 
27 class TestSnapStrategy;
28 class KoPathPoint;
29 class KoSnapProxy;
30 class KoViewConverter;
31 
32 class QTransform;
33 class QPainterPath;
34 
35 class KRITAFLAKE_EXPORT KoSnapStrategy
36 {
37 public:
38     KoSnapStrategy(KoSnapGuide::Strategy type);
~KoSnapStrategy()39     virtual ~KoSnapStrategy() {};
40 
41     virtual bool snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance) = 0;
42 
43     /// returns the strategies type
44     KoSnapGuide::Strategy type() const;
45 
46     static qreal squareDistance(const QPointF &p1, const QPointF &p2);
47     static qreal scalarProduct(const QPointF &p1, const QPointF &p2);
48 
49     /// returns the snapped position form the last call to snapToPoints
50     QPointF snappedPosition() const;
51 
52     /// returns the current snap strategy decoration
53     virtual QPainterPath decoration(const KoViewConverter &converter) const = 0;
54 
55 protected:
56     /// sets the current snapped position
57     void setSnappedPosition(const QPointF &position);
58 
59 private:
60     KoSnapGuide::Strategy m_snapType;
61     QPointF m_snappedPosition;
62 };
63 
64 /// snaps to x- or y-coordinates of path points
65 class KRITAFLAKE_EXPORT OrthogonalSnapStrategy : public KoSnapStrategy
66 {
67 public:
68     OrthogonalSnapStrategy();
69     bool snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance) override;
70     QPainterPath decoration(const KoViewConverter &converter) const override;
71 private:
72     QLineF m_hLine;
73     QLineF m_vLine;
74 };
75 
76 /// snaps to path points
77 class KRITAFLAKE_EXPORT NodeSnapStrategy : public KoSnapStrategy
78 {
79 public:
80     NodeSnapStrategy();
81     bool snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance) override;
82     QPainterPath decoration(const KoViewConverter &converter) const override;
83 };
84 
85 /// snaps extension lines of path shapes
86 class KRITAFLAKE_EXPORT ExtensionSnapStrategy : public KoSnapStrategy
87 {
88     friend class TestSnapStrategy;
89 public:
90     ExtensionSnapStrategy();
91     bool snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance) override;
92     QPainterPath decoration(const KoViewConverter &converter) const override;
93 private:
94     qreal project(const QPointF &lineStart , const QPointF &lineEnd, const QPointF &point);
95     QPointF extensionDirection(KoPathPoint * point, const QTransform &matrix);
96     bool snapToExtension(QPointF &position, KoPathPoint * point, const QTransform &matrix);
97     QList<QLineF> m_lines;
98 };
99 
100 /// snaps to intersections of shapes
101 class KRITAFLAKE_EXPORT IntersectionSnapStrategy : public KoSnapStrategy
102 {
103 public:
104     IntersectionSnapStrategy();
105     bool snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance) override;
106     QPainterPath decoration(const KoViewConverter &converter) const override;
107 };
108 
109 /// snaps to the canvas grid
110 class KRITAFLAKE_EXPORT GridSnapStrategy : public KoSnapStrategy
111 {
112 public:
113     GridSnapStrategy();
114     bool snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance) override;
115     QPainterPath decoration(const KoViewConverter &converter) const override;
116 };
117 
118 /// snaps to shape bounding boxes
119 class KRITAFLAKE_EXPORT BoundingBoxSnapStrategy : public KoSnapStrategy
120 {
121     friend class TestSnapStrategy;
122 public:
123     BoundingBoxSnapStrategy();
124     bool snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance) override;
125     QPainterPath decoration(const KoViewConverter &converter) const override;
126 private:
127     qreal squareDistanceToLine(const QPointF &lineA, const QPointF &lineB, const QPointF &point, QPointF &pointOnLine);
128     QPointF m_boxPoints[5];
129 };
130 
131 // KoGuidesData has been moved into Krita. Please port this class!
132 //
133 /// snaps to line guides
134 // class KRITAFLAKE_EXPORT LineGuideSnapStrategy : public KoSnapStrategy
135 // {
136 // public:
137 //     LineGuideSnapStrategy();
138 //     virtual bool snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance);
139 //     virtual QPainterPath decoration(const KoViewConverter &converter) const;
140 // private:
141 //     int m_orientation;
142 // };
143 
144 #endif // KOSNAPSTRATEGY_H
145