Krita Source Code Documentation
Loading...
Searching...
No Matches
InfiniteRulerAssistant Class Reference

#include <InfiniteRulerAssistant.h>

+ Inheritance diagram for InfiniteRulerAssistant:

Classes

struct  ClippingResult
 

Public Member Functions

void adjustLine (QPointF &point, QPointF &strokeBegin) override
 
QPointF adjustPosition (const QPointF &point, const QPointF &strokeBegin, const bool snapToAny, qreal moveThresholdPt) override
 
KisPaintingAssistantSP clone (QMap< KisPaintingAssistantHandleSP, KisPaintingAssistantHandleSP > &handleMap) const override
 
QPointF getDefaultEditorPosition () const override
 
 InfiniteRulerAssistant ()
 
bool isAssistantComplete () const override
 
int numHandles () const override
 
- Public Member Functions inherited from RulerAssistant
void adjustLine (QPointF &point, QPointF &strokeBegin) override
 
QPointF adjustPosition (const QPointF &point, const QPointF &strokeBegin, const bool snapToAny, qreal moveThresholdPt) override
 
KisPaintingAssistantSP clone (QMap< KisPaintingAssistantHandleSP, KisPaintingAssistantHandleSP > &handleMap) const override
 
void enableFixedLength (bool enabled)
 
void ensureLength ()
 
qreal fixedLength () const
 
QString fixedLengthUnit () const
 
QPointF getDefaultEditorPosition () const override
 
bool hasFixedLength () const
 
bool isAssistantComplete () const override
 
bool loadCustomXml (QXmlStreamReader *xml) override
 
int minorSubdivisions () const
 
int numHandles () const override
 
 RulerAssistant ()
 
void saveCustomXml (QXmlStreamWriter *xml) override
 
void setFixedLength (qreal length)
 
void setFixedLengthUnit (QString unit)
 
void setMinorSubdivisions (int subdivisions)
 
void setSubdivisions (int subdivisions)
 
int subdivisions () const
 
- Public Member Functions inherited from KisPaintingAssistant
void addHandle (KisPaintingAssistantHandleSP handle, HandleType type)
 
bool areTwoPointsClose (const QPointF &pointOne, const QPointF &pointTwo)
 
QColor assistantCustomColor ()
 
KisPaintingAssistantHandleSP bottomLeft ()
 
const KisPaintingAssistantHandleSP bottomLeft () const
 
KisPaintingAssistantHandleSP bottomMiddle ()
 
const KisPaintingAssistantHandleSP bottomMiddle () const
 
KisPaintingAssistantHandleSP bottomRight ()
 
const KisPaintingAssistantHandleSP bottomRight () const
 
virtual bool canBeLocal () const
 canBeLocal
 
KisPaintingAssistantHandleSP closestCornerHandleFromPoint (QPointF point)
 
void copySharedData (KisPaintingAssistantSP assistant)
 
void drawError (QPainter &painter, const QPainterPath &path)
 
void drawPath (QPainter &painter, const QPainterPath &path, bool drawActive=true)
 
void drawPreview (QPainter &painter, const QPainterPath &path)
 
void drawX (QPainter &painter, const QPointF &pt)
 
QPointF editorWidgetOffset ()
 
QColor effectiveAssistantColor () const
 
virtual void endStroke ()
 
void findPerspectiveAssistantHandleLocation ()
 
virtual QPointF getEditorPosition () const
 
QList< KisPaintingAssistantHandleSPhandles ()
 
const QList< KisPaintingAssistantHandleSP > & handles () const
 
const QString & id () const
 
bool isDuplicating ()
 isDuplicating
 
bool isLocal () const
 isLocal
 
bool isLocked ()
 isLocked
 
bool isSnappingActive () const
 
 KisPaintingAssistant (const QString &id, const QString &name)
 
KisPaintingAssistantHandleSP leftMiddle ()
 
const KisPaintingAssistantHandleSP leftMiddle () const
 
void loadXml (KoStore *store, QMap< int, KisPaintingAssistantHandleSP > &handleMap, QString path)
 
const QString & name () const
 
KisPaintingAssistantHandleSP oppHandleOne ()
 
void replaceHandle (KisPaintingAssistantHandleSP _handle, KisPaintingAssistantHandleSP _with)
 
KisPaintingAssistantHandleSP rightMiddle ()
 
const KisPaintingAssistantHandleSP rightMiddle () const
 
QByteArray saveXml (QMap< KisPaintingAssistantHandleSP, int > &handleMap)
 
void saveXmlList (QDomDocument &doc, QDomElement &assistantsElement, int count)
 
virtual void setAdjustedBrushPosition (const QPointF position)
 
void setAssistantCustomColor (QColor color)
 
void setAssistantGlobalColorCache (const QColor &color)
 
void setDecorationThickness (int thickness)
 
void setDuplicating (bool value)
 setDuplicating
 
void setEditorWidgetOffset (QPointF offset)
 
virtual void setFollowBrushPosition (bool follow)
 
void setLocal (bool value)
 setLocal
 
void setLocked (bool value)
 setLocked
 
void setSnappingActive (bool set)
 
void setUseCustomColor (bool useCustomColor)
 
QList< KisPaintingAssistantHandleSPsideHandles ()
 
const QList< KisPaintingAssistantHandleSP > & sideHandles () const
 
KisPaintingAssistantHandleSP topLeft ()
 
const KisPaintingAssistantHandleSP topLeft () const
 
KisPaintingAssistantHandleSP topMiddle ()
 
const KisPaintingAssistantHandleSP topMiddle () const
 
KisPaintingAssistantHandleSP topRight ()
 
const KisPaintingAssistantHandleSP topRight () const
 
virtual void transform (const QTransform &transform)
 
void uncache ()
 
bool useCustomColor ()
 
QPointF viewportConstrainedEditorPosition (const KisCoordinatesConverter *converter, const QSize editorSize)
 
virtual ~KisPaintingAssistant ()
 

Protected Member Functions

void drawAssistant (QPainter &gc, const QRectF &updateRect, const KisCoordinatesConverter *converter, bool cached=true, KisCanvas2 *canvas=0, bool assistantVisible=true, bool previewVisible=true) override
 
- Protected Member Functions inherited from RulerAssistant
void drawAssistant (QPainter &gc, const QRectF &updateRect, const KisCoordinatesConverter *converter, bool cached, KisCanvas2 *canvas, bool assistantVisible=true, bool previewVisible=true) override
 
void drawCache (QPainter &gc, const KisCoordinatesConverter *converter, bool assistantVisible=true) override
 performance layer where the graphics can be drawn from a cache instead of generated every render update
 
 RulerAssistant (const QString &id, const QString &name)
 
 RulerAssistant (const RulerAssistant &rhs, QMap< KisPaintingAssistantHandleSP, KisPaintingAssistantHandleSP > &handleMap)
 
- Protected Member Functions inherited from KisPaintingAssistant
virtual QRect boundingRect () const
 
QPointF effectiveBrushPosition (const KisCoordinatesConverter *converter, KisCanvas2 *canvas) const
 Query the effective brush position to be used for preview lines. This is intended to be used for painting the dynamic preview lines for assistants that feature them. Affected by setAdjustedBrushPosition() and setFollowBrushPosition().
 
virtual KisPaintingAssistantHandleSP firstLocalHandle () const
 firstLocalHandle Note: this doesn't guarantee it will be the topleft corner! For that, use getLocalRect().topLeft() The only purpose of those functions to exist is to be able to put getLocalRect() function in the KisPaintingAssistant instead of reimplementing it in every specific assistant.
 
QRectF getLocalRect () const
 getLocalRect The function deals with local handles not being topLeft and bottomRight gracefully and returns a correct rectangle. Thanks to that the user can place handles in a "wrong" order or move them around but the local rectangle will still be correct.
 
void initHandles (QList< KisPaintingAssistantHandleSP > _handles)
 
 KisPaintingAssistant (const KisPaintingAssistant &rhs, QMap< KisPaintingAssistantHandleSP, KisPaintingAssistantHandleSP > &handleMap)
 
QPointF pixelToView (const QPoint pixelCoords) const
 
virtual KisPaintingAssistantHandleSP secondLocalHandle () const
 secondLocalHandle Note: this doesn't guarantee it will be the bottomRight corner! For that, use getLocalRect().bottomRight() (and remember that for QRect bottomRight() works differently than for QRectF, so don't convert to QRect before accessing the corner)
 

Private Member Functions

void drawSubdivisions (QPainter &gc, const KisCoordinatesConverter *converter)
 
 InfiniteRulerAssistant (const InfiniteRulerAssistant &rhs, QMap< KisPaintingAssistantHandleSP, KisPaintingAssistantHandleSP > &handleMap)
 
QPointF project (const QPointF &pt, const QPointF &strokeBegin, const bool checkForInitialMovement, qreal moveThresholdPt)
 

Static Private Member Functions

static ClippingResult clipLineParametric (QLineF line, QRectF rect, bool extendFirst=true, bool extendSecond=true)
 

Additional Inherited Members

- Static Public Member Functions inherited from KisPaintingAssistant
static QList< KisPaintingAssistantSPcloneAssistantList (const QList< KisPaintingAssistantSP > &list)
 
static double norm2 (const QPointF &p)
 
- Protected Attributes inherited from KisPaintingAssistant
QList< KisPaintingAssistantHandleSPm_handles
 
bool m_hasBeenInsideLocalRect {false}
 

Detailed Description

Definition at line 21 of file InfiniteRulerAssistant.h.

Constructor & Destructor Documentation

◆ InfiniteRulerAssistant() [1/2]

InfiniteRulerAssistant::InfiniteRulerAssistant ( )

Definition at line 26 of file InfiniteRulerAssistant.cc.

27 : RulerAssistant("infinite ruler", i18n("Infinite Ruler assistant"))
28{
29}

◆ InfiniteRulerAssistant() [2/2]

InfiniteRulerAssistant::InfiniteRulerAssistant ( const InfiniteRulerAssistant & rhs,
QMap< KisPaintingAssistantHandleSP, KisPaintingAssistantHandleSP > & handleMap )
explicitprivate

Definition at line 31 of file InfiniteRulerAssistant.cc.

32 : RulerAssistant(rhs, handleMap)
33{
34}

Member Function Documentation

◆ adjustLine()

void InfiniteRulerAssistant::adjustLine ( QPointF & point,
QPointF & strokeBegin )
overridevirtual

Implements KisPaintingAssistant.

Definition at line 72 of file InfiniteRulerAssistant.cc.

73{
74
75 point = project(point, strokeBegin, false, 0.0);
76 strokeBegin = project(strokeBegin, strokeBegin, false, 0.0);
77}
QPointF project(const QPointF &pt, const QPointF &strokeBegin, const bool checkForInitialMovement, qreal moveThresholdPt)

References project().

◆ adjustPosition()

QPointF InfiniteRulerAssistant::adjustPosition ( const QPointF & point,
const QPointF & strokeBegin,
const bool snapToAny,
qreal moveThresholdPt )
overridevirtual

Adjust the position given in parameter.

Parameters
pointthe coordinates in point in the document reference
strokeBeginthe coordinates of the beginning of the stroke
snapToAnybecause now assistants can be composited out of multiple inside assistants. snapToAny true means that you can use any of the inside assistant, while it being false means you should use the last used one. The logic determining when it happens (first stroke etc.) is in the decoration, so those two options are enough.
moveThresholdPtthe threshold for the "move" of the cursor measured in pt (usually equals to 2px in screen coordinates converted to pt)

Implements KisPaintingAssistant.

Definition at line 67 of file InfiniteRulerAssistant.cc.

68{
69 return project(pt, strokeBegin, true, moveThresholdPt);
70}

References project().

◆ clipLineParametric()

InfiniteRulerAssistant::ClippingResult InfiniteRulerAssistant::clipLineParametric ( QLineF line,
QRectF rect,
bool extendFirst = true,
bool extendSecond = true )
staticprivate

Definition at line 201 of file InfiniteRulerAssistant.cc.

201 {
202 double dx = line.x2() - line.x1();
203 double dy = line.y2() - line.y1();
204
205 double q1 = line.x1() - rect.x();
206 double q2 = rect.x() + rect.width() - line.x1();
207 double q3 = line.y1() - rect.y();
208 double q4 = rect.y() + rect.height() - line.y1();
209
210 QVector<double> p = QVector<double>({-dx, dx, -dy, dy});
212
213 double tmin = extendFirst ? -std::numeric_limits<double>::infinity() : 0.0;
214 double tmax = extendSecond ? +std::numeric_limits<double>::infinity() : 1.0;
215
216 for (int i = 0; i < p.length(); i++) {
217
218 if (p[i] == 0 && q[i] < 0) {
219 // Line is parallel to this boundary and outside of it
220 return ClippingResult{false, 0, 0};
221
222 } else if (p[i] < 0) {
223 // Line moves into this boundary with increasing t
224 // Set minimum t where it just comes in
225 double t = q[i] / p[i];
226 if (t > tmin) {
227 tmin = t;
228 }
229
230 } else if (p[i] > 0) {
231 // Line moves out of this boundary with increasing t
232 // Set maximum t where it is still inside
233 double t = q[i] / p[i];
234 if (t < tmax) {
235 tmax = t;
236 }
237 }
238 }
239
240 // The line intersects the rectangle if tmin < tmax.
241 return ClippingResult{tmin < tmax, tmin, tmax};
242}
QPointF q1
const Params2D p
QPointF q3
QPointF q2

References p, q1, q2, and q3.

◆ clone()

KisPaintingAssistantSP InfiniteRulerAssistant::clone ( QMap< KisPaintingAssistantHandleSP, KisPaintingAssistantHandleSP > & handleMap) const
overridevirtual

Implements KisPaintingAssistant.

Definition at line 36 of file InfiniteRulerAssistant.cc.

37{
38 return KisPaintingAssistantSP(new InfiniteRulerAssistant(*this, handleMap));
39}
QSharedPointer< KisPaintingAssistant > KisPaintingAssistantSP
Definition kis_types.h:189

References InfiniteRulerAssistant().

◆ drawAssistant()

void InfiniteRulerAssistant::drawAssistant ( QPainter & gc,
const QRectF & updateRect,
const KisCoordinatesConverter * converter,
bool cached = true,
KisCanvas2 * canvas = 0,
bool assistantVisible = true,
bool previewVisible = true )
overrideprotectedvirtual

Reimplemented from KisPaintingAssistant.

Definition at line 169 of file InfiniteRulerAssistant.cc.

170{
171 gc.save();
172 gc.resetTransform();
173
174 if (isAssistantComplete() && isSnappingActive() && previewVisible) {
175
176 // Extend the line to the full viewport
177 QTransform initialTransform = converter->documentToWidgetTransform();
178 QLineF snapLine = QLineF(initialTransform.map(*handles()[0]), initialTransform.map(*handles()[1]));
179 QRect viewport = gc.viewport();
180 KisAlgebra2D::intersectLineRect(snapLine, viewport, true);
181
182 // Draw as preview (thin lines)
183 QPainterPath path;
184 path.moveTo(snapLine.p1());
185 path.lineTo(snapLine.p2());
186 drawPreview(gc, path);
187
188 // Add the extended subdivisions, if active
189 // When the number of subdivisions (or minor subdivisions) is set to
190 // 0, the respective feature is turned off and won't be rendered.
191 if (subdivisions() > 0) {
192 drawSubdivisions(gc, converter);
193 }
194 }
195
196 gc.restore();
197
198 RulerAssistant::drawAssistant(gc, updateRect, converter, cached, canvas, assistantVisible, previewVisible);
199}
void drawSubdivisions(QPainter &gc, const KisCoordinatesConverter *converter)
bool isAssistantComplete() const override
void drawPreview(QPainter &painter, const QPainterPath &path)
const QList< KisPaintingAssistantHandleSP > & handles() const
void drawAssistant(QPainter &gc, const QRectF &updateRect, const KisCoordinatesConverter *converter, bool cached, KisCanvas2 *canvas, bool assistantVisible=true, bool previewVisible=true) override
int subdivisions() const
bool intersectLineRect(QLineF &line, const QRect rect, bool extend)

References KisCoordinatesConverter::documentToWidgetTransform(), RulerAssistant::drawAssistant(), KisPaintingAssistant::drawPreview(), drawSubdivisions(), KisPaintingAssistant::handles(), KisAlgebra2D::intersectLineRect(), isAssistantComplete(), KisPaintingAssistant::isSnappingActive(), and RulerAssistant::subdivisions().

◆ drawSubdivisions()

void InfiniteRulerAssistant::drawSubdivisions ( QPainter & gc,
const KisCoordinatesConverter * converter )
private

Definition at line 79 of file InfiniteRulerAssistant.cc.

79 {
80 if (subdivisions() == 0) {
81 return;
82 }
83
84 // Get handle positions
85 QTransform document2widget = converter->documentToWidgetTransform();
86
87 QPointF p1 = document2widget.map(*handles()[0]);
88 QPointF p2 = document2widget.map(*handles()[1]);
89
90 const qreal scale = 16.0 / 2;
91 const qreal minorScale = scale / 2;
92 const QRectF clipping = QRectF(gc.viewport()).adjusted(-scale, -scale, scale, scale);
93 // If the lines would end up closer to each other than this threshold (in
94 // screen coordinates), they are not rendered, as they wouldn't be
95 // distinguishable anymore.
96 const qreal threshold = 3.0;
97
98 // Calculate line direction and normal vector
99 QPointF delta = p2 - p1;
100 qreal length = sqrt(KisPaintingAssistant::norm2(delta));
101 qreal stepsize = length / subdivisions();
102
103 // Only draw if lines are far enough apart
104 if (stepsize >= threshold) {
105 QPointF normal = QPointF(delta.y(), -delta.x());
106 normal /= length;
107
108 // Clip the line to the viewport and find the t parameters for these
109 // points
110 ClippingResult res = clipLineParametric(QLineF(p1, p2), clipping);
111 // Abort if line is outside clipping area
112 if (!res.intersects) {
113 return;
114 }
115 // Calculate indices to start and end the subdivisions on screen by
116 // rounding further "away" from the visible area, ensuring that all
117 // divisions that could be visible are actually drawn
118 int istart = (int) floor(res.tmin * subdivisions());
119 int iend = (int) ceil(res.tmax * subdivisions());
120
121 QPainterPath path;
122 QPainterPath highlight;
123
124 // Draw the major subdivisions
125 for (int ii = istart; ii < iend; ++ii) {
126 QPointF pos = p1 + delta * ((qreal)ii / subdivisions());
127 // No additional clipping check needed, since we're already
128 // constrained inside it by the ii values.
129 // However, don't draw over the thicker lines where the actual
130 // ruler is located and already drawn!
131 if (0 <= ii && ii < subdivisions()) {
132 continue;
133 }
134 // Special case at ii == subdivs: minor subdivisions are needed
135 // here, but not the major one, as this is the last line drawn of
136 // the main ruler.
137 if (ii != subdivisions()) {
138 // Highlight the integer multiples of the ruler length
139 if (ii % subdivisions() == 0) {
140 highlight.moveTo(pos - normal * scale);
141 highlight.lineTo(pos + normal * scale);
142 } else {
143 path.moveTo(pos - normal * scale);
144 path.lineTo(pos + normal * scale);
145 }
146 }
147
148 // Draw minor subdivisions, if they exist (implicit check due to
149 // the loop bounds)
150 // Skip if major subdivisions are too close already
151 if (stepsize / minorSubdivisions() < threshold)
152 continue;
153 // Draw minor marks in between the major ones
154 for (int jj = 1; jj < minorSubdivisions(); ++jj) {
155 QPointF mpos = pos + delta * ((qreal)jj / (subdivisions() * minorSubdivisions()));
156
157 path.moveTo(mpos - normal * minorScale);
158 path.lineTo(mpos + normal * minorScale);
159 }
160 }
161
162 // Draw highlight as regular path (2 px wide)
163 drawPath(gc, highlight);
164 // Draw normal lines as preview (1 px wide)
165 drawPreview(gc, path);
166 }
167}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
QPointF p2
QPointF p1
static ClippingResult clipLineParametric(QLineF line, QRectF rect, bool extendFirst=true, bool extendSecond=true)
void drawPath(QPainter &painter, const QPainterPath &path, bool drawActive=true)
static double norm2(const QPointF &p)
int minorSubdivisions() const

References clipLineParametric(), KisCoordinatesConverter::documentToWidgetTransform(), KisPaintingAssistant::drawPath(), KisPaintingAssistant::drawPreview(), KisPaintingAssistant::handles(), InfiniteRulerAssistant::ClippingResult::intersects, length(), RulerAssistant::minorSubdivisions(), KisPaintingAssistant::norm2(), p1, p2, RulerAssistant::subdivisions(), InfiniteRulerAssistant::ClippingResult::tmax, and InfiniteRulerAssistant::ClippingResult::tmin.

◆ getDefaultEditorPosition()

QPointF InfiniteRulerAssistant::getDefaultEditorPosition ( ) const
overridevirtual

Implements KisPaintingAssistant.

Definition at line 244 of file InfiniteRulerAssistant.cc.

245{
246 return (*handles()[0]);
247}

References KisPaintingAssistant::handles().

◆ isAssistantComplete()

bool InfiniteRulerAssistant::isAssistantComplete ( ) const
overridevirtual

determines if the assistant has enough handles to be considered created new assistants get in a "creation" phase where they are currently being made on the canvas it will return false if we are in the middle of creating the assistant.

Reimplemented from KisPaintingAssistant.

Definition at line 249 of file InfiniteRulerAssistant.cc.

250{
251 return handles().size() >= 2;
252}

References KisPaintingAssistant::handles().

◆ numHandles()

int InfiniteRulerAssistant::numHandles ( ) const
inlineoverridevirtual

Implements KisPaintingAssistant.

Definition at line 29 of file InfiniteRulerAssistant.h.

29{ return 2; }

◆ project()

QPointF InfiniteRulerAssistant::project ( const QPointF & pt,
const QPointF & strokeBegin,
const bool checkForInitialMovement,
qreal moveThresholdPt )
private

Definition at line 41 of file InfiniteRulerAssistant.cc.

42{
43 Q_ASSERT(isAssistantComplete());
44 //code nicked from the perspective ruler.
45 qreal dx = pt.x() - strokeBegin.x();
46 qreal dy = pt.y() - strokeBegin.y();
47 if (checkForInitialMovement && KisAlgebra2D::norm(QPointF(dx, dy)) < moveThresholdPt) {
48 // allow some movement before snapping
49 return strokeBegin;
50 }
51
52 QLineF snapLine = QLineF(*handles()[0], *handles()[1]);
53
54 dx = snapLine.dx();
55 dy = snapLine.dy();
56 const qreal
57 dx2 = dx * dx,
58 dy2 = dy * dy,
59 invsqrlen = 1.0 / (dx2 + dy2);
60 QPointF r(dx2 * pt.x() + dy2 * snapLine.x1() + dx * dy * (pt.y() - snapLine.y1()),
61 dx2 * snapLine.y1() + dy2 * pt.y() + dx * dy * (pt.x() - snapLine.x1()));
62 r *= invsqrlen;
63 return r;
64 //return pt;
65}
qreal norm(const T &a)

References KisPaintingAssistant::handles(), isAssistantComplete(), and KisAlgebra2D::norm().


The documentation for this class was generated from the following files: