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

#include <ShapeShearStrategy.h>

+ Inheritance diagram for ShapeShearStrategy:

Public Member Functions

KUndo2CommandcreateCommand () override
 
void finishInteraction (Qt::KeyboardModifiers modifiers) override
 
void handleMouseMove (const QPointF &mouseLocation, Qt::KeyboardModifiers modifiers) override
 
void paint (QPainter &painter, const KoViewConverter &converter) override
 
 ShapeShearStrategy (KoToolBase *tool, KoSelection *selection, const QPointF &clicked, KoFlake::SelectionHandle direction)
 
 ~ShapeShearStrategy () override
 
- Public Member Functions inherited from KoInteractionStrategy
virtual void cancelInteraction ()
 
 KoInteractionStrategy (KoToolBase *parent)
 constructor
 
KoToolBasetool () const
 
virtual ~KoInteractionStrategy ()
 Destructor.
 

Private Attributes

bool m_bottom {false}
 
qreal m_initialSelectionAngle {0.0}
 
QSizeF m_initialSize
 
bool m_isMirrored {false}
 
bool m_left {false}
 
QList< QTransform > m_oldTransforms
 
bool m_right {false}
 
QTransform m_shearMatrix
 
QPointF m_solidPoint
 
QPointF m_start
 
bool m_top {false}
 
QList< KoShape * > m_transformedShapesAndSelection
 

Additional Inherited Members

- Protected Member Functions inherited from KoInteractionStrategy
uint decorationThickness () const
 
uint grabSensitivity () const
 Convenience function to get the global grab sensitivity.
 
uint handleRadius () const
 Convenience function to get the global handle radius.
 
 KoInteractionStrategy (KoInteractionStrategyPrivate &)
 constructor
 
- Protected Attributes inherited from KoInteractionStrategy
KoInteractionStrategyPrivated_ptr
 

Detailed Description

A strategy for the KoInteractionTool. This strategy is invoked when the user starts a shear of a selection of objects, the strategy will then shear the objects interactively and provide a command afterwards.

Definition at line 26 of file ShapeShearStrategy.h.

Constructor & Destructor Documentation

◆ ShapeShearStrategy()

ShapeShearStrategy::ShapeShearStrategy ( KoToolBase * tool,
KoSelection * selection,
const QPointF & clicked,
KoFlake::SelectionHandle direction )

Constructor that starts to rotate the objects.

Parameters
toolthe parent tool which controls this strategy
clickedthe initial point that the user depressed (in pt).
directionthe handle that was grabbed

The outline of the selection should look as if it is also sheared, so we add it to the transformed shapes list.

Definition at line 28 of file ShapeShearStrategy.cpp.

30 , m_start(clicked)
31{
38
39 Q_FOREACH (KoShape *shape, m_transformedShapesAndSelection) {
41 }
42
43 // Even though we aren't currently activated by the corner handles we might as well code like it
44 switch (direction) {
46 m_top = true; m_bottom = false; m_left = false; m_right = false; break;
48 m_top = true; m_bottom = false; m_left = false; m_right = true; break;
50 m_top = false; m_bottom = false; m_left = false; m_right = true; break;
52 m_top = false; m_bottom = true; m_left = false; m_right = true; break;
54 m_top = false; m_bottom = true; m_left = false; m_right = false; break;
56 m_top = false; m_bottom = true; m_left = true; m_right = false; break;
58 m_top = false; m_bottom = false; m_left = true; m_right = false; break;
60 m_top = true; m_bottom = false; m_left = true; m_right = false; break;
61 default:
62 Q_UNREACHABLE();
63 ;// throw exception ? TODO
64 }
65 m_initialSize = selection->size();
66 m_solidPoint = QPointF(m_initialSize.width() / 2, m_initialSize.height() / 2);
67
68 if (m_top) {
69 m_solidPoint += QPointF(0, m_initialSize.height() / 2);
70 } else if (m_bottom) {
71 m_solidPoint -= QPointF(0, m_initialSize.height() / 2);
72 }
73 if (m_left) {
74 m_solidPoint += QPointF(m_initialSize.width() / 2, 0);
75 } else if (m_right) {
76 m_solidPoint -= QPointF(m_initialSize.width() / 2, 0);
77 }
78
79 m_solidPoint = selection->absoluteTransformation().map(selection->outlineRect().topLeft() + m_solidPoint);
80
81 QPointF edge;
82 qreal angle = 0.0;
83 if (m_top) {
84 edge = selection->absolutePosition(KoFlake::BottomLeft) - selection->absolutePosition(KoFlake::BottomRight);
85 angle = 180.0;
86 } else if (m_bottom) {
87 edge = selection->absolutePosition(KoFlake::TopRight) - selection->absolutePosition(KoFlake::TopLeft);
88 angle = 0.0;
89 } else if (m_left) {
90 edge = selection->absolutePosition(KoFlake::BottomLeft) - selection->absolutePosition(KoFlake::TopLeft);
91 angle = 90.0;
92 } else if (m_right) {
93 edge = selection->absolutePosition(KoFlake::TopRight) - selection->absolutePosition(KoFlake::BottomRight);
94 angle = 270.0;
95 }
96 qreal currentAngle = atan2(edge.y(), edge.x()) / M_PI * 180;
97 m_initialSelectionAngle = currentAngle - angle;
98
99 // use cross product of top edge and left edge of selection bounding rect
100 // to determine if the selection is mirrored
101 QPointF top = selection->absolutePosition(KoFlake::TopRight) - selection->absolutePosition(KoFlake::TopLeft);
102 QPointF left = selection->absolutePosition(KoFlake::BottomLeft) - selection->absolutePosition(KoFlake::TopLeft);
103 m_isMirrored = (top.x() * left.y() - top.y() * left.x()) < 0.0;
104}
KoInteractionStrategy(KoToolBase *parent)
constructor
const QList< KoShape * > selectedEditableShapes() const
QTransform transformation() const
Returns the shapes local transformation matrix.
Definition KoShape.cpp:424
QList< KoShape * > m_transformedShapesAndSelection
QList< QTransform > m_oldTransforms
#define M_PI
Definition kis_global.h:111
KRITAIMAGE_EXPORT qreal atan2(qreal y, qreal x)
atan2 replacement
@ BottomRight
Definition KoFlake.h:94
@ TopRight
Definition KoFlake.h:88
@ TopLeft
Definition KoFlake.h:86
@ BottomLeft
Definition KoFlake.h:92
@ BottomRightHandle
The handle that is at the bottom right of a selection.
Definition KoFlake.h:59
@ BottomLeftHandle
The handle that is at the bottom left of a selection.
Definition KoFlake.h:61
@ RightMiddleHandle
The handle that is at the right - center of a selection.
Definition KoFlake.h:58
@ TopRightHandle
The handle that is at the top - right of a selection.
Definition KoFlake.h:57
@ TopLeftHandle
The handle that is at the top left of a selection.
Definition KoFlake.h:63
@ LeftMiddleHandle
The handle that is at the left center of a selection.
Definition KoFlake.h:62
@ TopMiddleHandle
The handle that is at the top - center of a selection.
Definition KoFlake.h:56
@ BottomMiddleHandle
The handle that is at the bottom center of a selection.
Definition KoFlake.h:60

References KoShape::absolutePosition(), KoShape::absoluteTransformation(), KoFlake::BottomLeft, KoFlake::BottomLeftHandle, KoFlake::BottomMiddleHandle, KoFlake::BottomRight, KoFlake::BottomRightHandle, KoFlake::LeftMiddleHandle, m_bottom, m_initialSelectionAngle, m_initialSize, m_isMirrored, m_left, m_oldTransforms, M_PI, m_right, m_solidPoint, m_top, m_transformedShapesAndSelection, KoSelection::outlineRect(), KoFlake::RightMiddleHandle, KoSelection::selectedEditableShapes(), KoSelection::size(), KoFlake::TopLeft, KoFlake::TopLeftHandle, KoFlake::TopMiddleHandle, KoFlake::TopRight, KoFlake::TopRightHandle, and KoShape::transformation().

◆ ~ShapeShearStrategy()

ShapeShearStrategy::~ShapeShearStrategy ( )
inlineoverride

Definition at line 36 of file ShapeShearStrategy.h.

36{}

Member Function Documentation

◆ createCommand()

KUndo2Command * ShapeShearStrategy::createCommand ( )
overridevirtual

For interactions that are undo-able this method should be implemented to return such a command. Implementations should return 0 otherwise.

Returns
a command, or 0.

Implements KoInteractionStrategy.

Definition at line 164 of file ShapeShearStrategy.cpp.

165{
166 QList<QTransform> newTransforms;
167 Q_FOREACH (KoShape *shape, m_transformedShapesAndSelection) {
168 newTransforms << shape->transformation();
169 }
170 const bool nothingChanged =
171 std::equal(m_oldTransforms.begin(), m_oldTransforms.end(),
172 newTransforms.begin(),
173 [] (const QTransform &t1, const QTransform &t2) {
174 return KisAlgebra2D::fuzzyMatrixCompare(t1, t2, 1e-6);
175 });
176
178 if (!nothingChanged) {
180 cmd->setText(kundo2_i18n("Shear"));
181 }
182 return cmd;
183}
void setText(const KUndo2MagicString &text)
KUndo2MagicString kundo2_i18n(const char *text)

References kundo2_i18n(), m_oldTransforms, m_transformedShapesAndSelection, KUndo2Command::setText(), and KoShape::transformation().

◆ finishInteraction()

void ShapeShearStrategy::finishInteraction ( Qt::KeyboardModifiers modifiers)
inlineoverridevirtual

Override to make final changes to the data on the end of an interaction.

Implements KoInteractionStrategy.

Definition at line 40 of file ShapeShearStrategy.h.

41 {
42 Q_UNUSED(modifiers);
43 }

◆ handleMouseMove()

void ShapeShearStrategy::handleMouseMove ( const QPointF & mouseLocation,
Qt::KeyboardModifiers modifiers )
overridevirtual

Extending classes should implement this method to update the selectedShapes based on the new mouse position.

Parameters
mouseLocationthe new location in pt
modifiersOR-ed set of keys pressed.

Implements KoInteractionStrategy.

Definition at line 106 of file ShapeShearStrategy.cpp.

107{
108 Q_UNUSED(modifiers);
109 QPointF shearVector = point - m_start;
110
111 QTransform m;
112 m.rotate(-m_initialSelectionAngle);
113 shearVector = m.map(shearVector);
114
115 qreal shearX = 0, shearY = 0;
116
117 if (m_top || m_left) {
118 shearVector = - shearVector;
119 }
120 if (m_top || m_bottom) {
121 shearX = m_initialSize.height() > 0 ? shearVector.x() / m_initialSize.height() : 0;
122 }
123 if (m_left || m_right) {
124 shearY = m_initialSize.width() > 0 ? shearVector.y() / m_initialSize.width() : 0;
125 }
126
127 // if selection is mirrored invert the shear values
128 if (m_isMirrored) {
129 shearX *= -1.0;
130 shearY *= -1.0;
131 }
132
133 const qreal maxSaneShear = 1e6;
134 if ((qAbs(shearX) == 0.0 && qAbs(shearY) == 0.0) ||
135 qAbs(shearX) > maxSaneShear ||
136 qAbs(shearY) > maxSaneShear) {
137
138 return;
139 }
140
141 QTransform matrix;
142 matrix.translate(m_solidPoint.x(), m_solidPoint.y());
143 matrix.rotate(m_initialSelectionAngle);
144 matrix.shear(shearX, shearY);
145 matrix.rotate(-m_initialSelectionAngle);
146 matrix.translate(-m_solidPoint.x(), -m_solidPoint.y());
147
148 QTransform applyMatrix = matrix * m_shearMatrix.inverted();
149
150 Q_FOREACH (KoShape *shape, m_transformedShapesAndSelection) {
151 const QRectF oldDirtyRect = shape->boundingRect();
152 shape->applyAbsoluteTransformation(applyMatrix);
153 shape->updateAbsolute(oldDirtyRect | shape->boundingRect());
154 }
155 m_shearMatrix = matrix;
156}
void applyAbsoluteTransformation(const QTransform &matrix)
Definition KoShape.cpp:400
virtual QRectF boundingRect() const
Get the bounding box of the shape.
Definition KoShape.cpp:335
virtual void updateAbsolute(const QRectF &rect) const
Definition KoShape.cpp:616

References KoShape::applyAbsoluteTransformation(), KoShape::boundingRect(), m_bottom, m_initialSelectionAngle, m_initialSize, m_isMirrored, m_left, m_right, m_shearMatrix, m_solidPoint, m_start, m_top, m_transformedShapesAndSelection, and KoShape::updateAbsolute().

◆ paint()

void ShapeShearStrategy::paint ( QPainter & painter,
const KoViewConverter & converter )
overridevirtual

Reimplement this if the action needs to draw a "blob" on the canvas; that is, a transient decoration like a rubber band.

Reimplemented from KoInteractionStrategy.

Definition at line 158 of file ShapeShearStrategy.cpp.

159{
160 Q_UNUSED(painter);
161 Q_UNUSED(converter);
162}

Member Data Documentation

◆ m_bottom

bool ShapeShearStrategy::m_bottom {false}
private

Definition at line 52 of file ShapeShearStrategy.h.

52{false};

◆ m_initialSelectionAngle

qreal ShapeShearStrategy::m_initialSelectionAngle {0.0}
private

Definition at line 54 of file ShapeShearStrategy.h.

54{0.0};

◆ m_initialSize

QSizeF ShapeShearStrategy::m_initialSize
private

Definition at line 49 of file ShapeShearStrategy.h.

◆ m_isMirrored

bool ShapeShearStrategy::m_isMirrored {false}
private

Definition at line 56 of file ShapeShearStrategy.h.

56{false};

◆ m_left

bool ShapeShearStrategy::m_left {false}
private

Definition at line 51 of file ShapeShearStrategy.h.

51{false};

◆ m_oldTransforms

QList<QTransform> ShapeShearStrategy::m_oldTransforms
private

Definition at line 57 of file ShapeShearStrategy.h.

◆ m_right

bool ShapeShearStrategy::m_right {false}
private

Definition at line 53 of file ShapeShearStrategy.h.

53{false};

◆ m_shearMatrix

QTransform ShapeShearStrategy::m_shearMatrix
private

Definition at line 55 of file ShapeShearStrategy.h.

◆ m_solidPoint

QPointF ShapeShearStrategy::m_solidPoint
private

Definition at line 48 of file ShapeShearStrategy.h.

◆ m_start

QPointF ShapeShearStrategy::m_start
private

Definition at line 47 of file ShapeShearStrategy.h.

◆ m_top

bool ShapeShearStrategy::m_top {false}
private

Definition at line 50 of file ShapeShearStrategy.h.

50{false};

◆ m_transformedShapesAndSelection

QList<KoShape *> ShapeShearStrategy::m_transformedShapesAndSelection
private

Definition at line 58 of file ShapeShearStrategy.h.


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