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 29 of file ShapeShearStrategy.cpp.

31 , m_start(clicked)
32{
39
40 Q_FOREACH (KoShape *shape, m_transformedShapesAndSelection) {
42 }
43
44 // Even though we aren't currently activated by the corner handles we might as well code like it
45 switch (direction) {
47 m_top = true; m_bottom = false; m_left = false; m_right = false; break;
49 m_top = true; m_bottom = false; m_left = false; m_right = true; break;
51 m_top = false; m_bottom = false; m_left = false; m_right = true; break;
53 m_top = false; m_bottom = true; m_left = false; m_right = true; break;
55 m_top = false; m_bottom = true; m_left = false; m_right = false; break;
57 m_top = false; m_bottom = true; m_left = true; m_right = false; break;
59 m_top = false; m_bottom = false; m_left = true; m_right = false; break;
61 m_top = true; m_bottom = false; m_left = true; m_right = false; break;
62 default:
63 Q_UNREACHABLE();
64 ;// throw exception ? TODO
65 }
66 m_initialSize = selection->size();
67 m_solidPoint = QPointF(m_initialSize.width() / 2, m_initialSize.height() / 2);
68
69 if (m_top) {
70 m_solidPoint += QPointF(0, m_initialSize.height() / 2);
71 } else if (m_bottom) {
72 m_solidPoint -= QPointF(0, m_initialSize.height() / 2);
73 }
74 if (m_left) {
75 m_solidPoint += QPointF(m_initialSize.width() / 2, 0);
76 } else if (m_right) {
77 m_solidPoint -= QPointF(m_initialSize.width() / 2, 0);
78 }
79
80 m_solidPoint = selection->absoluteTransformation().map(selection->outlineRect().topLeft() + m_solidPoint);
81
82 QPointF edge;
83 qreal angle = 0.0;
84 if (m_top) {
85 edge = selection->absolutePosition(KoFlake::BottomLeft) - selection->absolutePosition(KoFlake::BottomRight);
86 angle = 180.0;
87 } else if (m_bottom) {
88 edge = selection->absolutePosition(KoFlake::TopRight) - selection->absolutePosition(KoFlake::TopLeft);
89 angle = 0.0;
90 } else if (m_left) {
91 edge = selection->absolutePosition(KoFlake::BottomLeft) - selection->absolutePosition(KoFlake::TopLeft);
92 angle = 90.0;
93 } else if (m_right) {
94 edge = selection->absolutePosition(KoFlake::TopRight) - selection->absolutePosition(KoFlake::BottomRight);
95 angle = 270.0;
96 }
97 qreal currentAngle = atan2(edge.y(), edge.x()) / M_PI * 180;
98 m_initialSelectionAngle = currentAngle - angle;
99
100 // use cross product of top edge and left edge of selection bounding rect
101 // to determine if the selection is mirrored
102 QPointF top = selection->absolutePosition(KoFlake::TopRight) - selection->absolutePosition(KoFlake::TopLeft);
103 QPointF left = selection->absolutePosition(KoFlake::BottomLeft) - selection->absolutePosition(KoFlake::TopLeft);
104 m_isMirrored = (top.x() * left.y() - top.y() * left.x()) < 0.0;
105}
KoInteractionStrategy(KoToolBase *parent)
constructor
const QList< KoShape * > selectedEditableShapes() const
QTransform transformation() const
Returns the shapes local transformation matrix.
Definition KoShape.cpp:383
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 168 of file ShapeShearStrategy.cpp.

169{
170 QList<QTransform> newTransforms;
171 Q_FOREACH (KoShape *shape, m_transformedShapesAndSelection) {
172 newTransforms << shape->transformation();
173 }
174 const bool nothingChanged =
175 std::equal(m_oldTransforms.begin(), m_oldTransforms.end(),
176 newTransforms.begin(),
177 [] (const QTransform &t1, const QTransform &t2) {
178 return KisAlgebra2D::fuzzyMatrixCompare(t1, t2, 1e-6);
179 });
180
182 if (!nothingChanged) {
184 cmd->setText(kundo2_i18n("Shear"));
185 }
186 return cmd;
187}
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 107 of file ShapeShearStrategy.cpp.

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

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

◆ 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 162 of file ShapeShearStrategy.cpp.

163{
164 Q_UNUSED(painter);
165 Q_UNUSED(converter);
166}

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: