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

#include <ShapeResizeStrategy.h>

+ Inheritance diagram for ShapeResizeStrategy:

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
 
 ShapeResizeStrategy (KoToolBase *tool, KoSelection *selection, const QPointF &clicked, KoFlake::SelectionHandle direction, bool forceUniformScalingMode)
 
 ~ShapeResizeStrategy () override
 
- Public Member Functions inherited from KoInteractionStrategy
virtual void cancelInteraction ()
 
 KoInteractionStrategy (KoToolBase *parent)
 constructor
 
KoToolBasetool () const
 
virtual ~KoInteractionStrategy ()
 Destructor.
 

Private Member Functions

void resizeBy (const QPointF &stillPoint, qreal zoomX, qreal zoomY)
 

Private Attributes

bool m_bottom {false}
 
QScopedPointer< KoShapeResizeCommandm_executedCommand
 
bool m_forceUniformScalingMode {false}
 
QPointF m_globalCenterPoint
 
QPointF m_globalStillPoint
 
QSizeF m_initialSelectionSize
 
bool m_left {false}
 
QTransform m_postScalingCoveringTransform
 
bool m_right {false}
 
QList< KoShape * > m_selectedShapes
 
QPointF m_start
 
bool m_top {false}
 
QTransform m_unwindMatrix
 

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 resize of a selection of objects, the strategy will then resize the objects interactively and provide a command afterwards.

Definition at line 28 of file ShapeResizeStrategy.h.

Constructor & Destructor Documentation

◆ ShapeResizeStrategy()

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

Constructor

Definition at line 28 of file ShapeResizeStrategy.cpp.

30 m_forceUniformScalingMode(forceUniformScalingMode)
31{
32 KIS_SAFE_ASSERT_RECOVER_RETURN(selection && selection->count() > 0);
33
35 m_start = clicked;
36
37 KoShape *shape = selection;
38
39 const qreal w = shape->size().width();
40 const qreal h = shape->size().height();
41
42 switch (direction) {
45 m_top = true; m_bottom = false; m_left = false; m_right = false;
46 m_globalStillPoint = QPointF(0.5 * w, h);
47 break;
50 m_top = true; m_bottom = false; m_left = false; m_right = true;
51 m_globalStillPoint = QPointF(0, h);
52 break;
55 m_top = false; m_bottom = false; m_left = false; m_right = true;
56 m_globalStillPoint = QPointF(0, 0.5 * h);
57 break;
60 m_top = false; m_bottom = true; m_left = false; m_right = true;
61 m_globalStillPoint = QPointF(0, 0);
62 break;
65 m_top = false; m_bottom = true; m_left = false; m_right = false;
66 m_globalStillPoint = QPointF(0.5 * w, 0);
67 break;
70 m_top = false; m_bottom = true; m_left = true; m_right = false;
71 m_globalStillPoint = QPointF(w, 0);
72 break;
75 m_top = false; m_bottom = false; m_left = true; m_right = false;
76 m_globalStillPoint = QPointF(w, 0.5 * h);
77 break;
80 m_top = true; m_bottom = false; m_left = true; m_right = false;
81 m_globalStillPoint = QPointF(w, h);
82 break;
83 default:
84 Q_ASSERT(0); // illegal 'corner'
85 }
86
87 const QPointF p0 = shape->outlineRect().topLeft();
90
91 m_unwindMatrix = shape->absoluteTransformation().inverted();
94
95
96 tool->setStatusText(i18n("Press CTRL to resize from center."));
98}
QPointF p0
KoSnapGuide * snapGuide
KoInteractionStrategy(KoToolBase *parent)
constructor
int count() const
return the selection count, i.e. the number of all selected shapes
const QList< KoShape * > selectedEditableShapes() const
virtual QSizeF size() const
Get the size of the shape in pt.
Definition KoShape.cpp:820
virtual QRectF outlineRect() const
Definition KoShape.cpp:637
QPointF absolutePosition(KoFlake::AnchorPosition anchor=KoFlake::Center) const
Definition KoShape.cpp:653
QTransform absoluteTransformation() const
Definition KoShape.cpp:382
static QList< KoShape * > linearizeSubtree(const QList< KoShape * > &shapes)
Definition KoShape.cpp:1381
QTransform transformation() const
Returns the shapes local transformation matrix.
Definition KoShape.cpp:424
void setIgnoredShapes(const QList< KoShape * > &ignoredShapes)
Sets list of ignored shapes.
KoCanvasBase * canvas() const
Returns the canvas the tool is working on.
void setStatusText(const QString &statusText)
QList< KoShape * > m_selectedShapes
QTransform m_postScalingCoveringTransform
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
@ BottomRight
Definition KoFlake.h:94
@ TopRight
Definition KoFlake.h:88
@ TopLeft
Definition KoFlake.h:86
@ BottomLeft
Definition KoFlake.h:92
@ Center
Definition KoFlake.h:90
@ 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, KoToolBase::canvas(), KoFlake::Center, KoSelection::count(), KIS_SAFE_ASSERT_RECOVER_RETURN, KoFlake::LeftMiddleHandle, KoShape::linearizeSubtree(), m_bottom, m_globalCenterPoint, m_globalStillPoint, m_initialSelectionSize, m_left, m_postScalingCoveringTransform, m_right, m_selectedShapes, m_start, m_top, m_unwindMatrix, KoShape::outlineRect(), p0, KoFlake::RightMiddleHandle, KoSelection::selectedEditableShapes(), KoSnapGuide::setIgnoredShapes(), KoToolBase::setStatusText(), KoShape::size(), KoCanvasBase::snapGuide, KoInteractionStrategy::tool(), KoFlake::TopLeft, KoFlake::TopLeftHandle, KoFlake::TopMiddleHandle, KoFlake::TopRight, KoFlake::TopRightHandle, and KoShape::transformation().

◆ ~ShapeResizeStrategy()

ShapeResizeStrategy::~ShapeResizeStrategy ( )
override

Definition at line 100 of file ShapeResizeStrategy.cpp.

101{
102
103}

Member Function Documentation

◆ createCommand()

KUndo2Command * ShapeResizeStrategy::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 210 of file ShapeResizeStrategy.cpp.

211{
212 tool()->canvas()->snapGuide()->reset();
213
214 if (m_executedCommand) {
215 m_executedCommand->setSkipOneRedo(true);
216 }
217
218 return m_executedCommand.take();
219}
void reset()
Resets the snap guide.
QScopedPointer< KoShapeResizeCommand > m_executedCommand

References KoToolBase::canvas(), m_executedCommand, KoSnapGuide::reset(), KoCanvasBase::snapGuide, and KoInteractionStrategy::tool().

◆ finishInteraction()

void ShapeResizeStrategy::finishInteraction ( Qt::KeyboardModifiers modifiers)
overridevirtual

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

Implements KoInteractionStrategy.

Definition at line 221 of file ShapeResizeStrategy.cpp.

222{
223 Q_UNUSED(modifiers);
224}

◆ handleMouseMove()

void ShapeResizeStrategy::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.

Do not let a shape be less than 1px in size in current view coordinates. If the user wants it to be smaller, he can just zoom-in a bit.

Implements KoInteractionStrategy.

Definition at line 105 of file ShapeResizeStrategy.cpp.

106{
107 QPointF newPos = tool()->canvas()->snapGuide()->snap(point, modifiers);
108
109 bool keepAspect = modifiers & Qt::ShiftModifier;
110 Q_FOREACH (KoShape *shape, m_selectedShapes) {
111 keepAspect = keepAspect || shape->keepAspectRatio();
112 }
113
114 qreal startWidth = m_initialSelectionSize.width();
115 if (startWidth < std::numeric_limits<qreal>::epsilon()) {
116 startWidth = std::numeric_limits<qreal>::epsilon();
117 }
118 qreal startHeight = m_initialSelectionSize.height();
119 if (startHeight < std::numeric_limits<qreal>::epsilon()) {
120 startHeight = std::numeric_limits<qreal>::epsilon();
121 }
122
123 QPointF distance = m_unwindMatrix.map(newPos) - m_unwindMatrix.map(m_start);
124
125 // guard against resizing zero width shapes, which would result in huge zoom factors
126 if (m_initialSelectionSize.width() < std::numeric_limits<qreal>::epsilon()) {
127 distance.rx() = 0.0;
128 }
129 // guard against resizing zero height shapes, which would result in huge zoom factors
130 if (m_initialSelectionSize.height() < std::numeric_limits<qreal>::epsilon()) {
131 distance.ry() = 0.0;
132 }
133
134 const bool scaleFromCenter = modifiers & Qt::ControlModifier;
135 if (scaleFromCenter) {
136 distance *= 2.0;
137 }
138
139 qreal newWidth = startWidth;
140 qreal newHeight = startHeight;
141
142 if (m_left) {
143 newWidth = startWidth - distance.x();
144 } else if (m_right) {
145 newWidth = startWidth + distance.x();
146 }
147
148 if (m_top) {
149 newHeight = startHeight - distance.y();
150 } else if (m_bottom) {
151 newHeight = startHeight + distance.y();
152 }
153
159 QSizeF minViewSize(1.0, 1.0);
160 QSizeF minDocSize = tool()->canvas()->viewConverter()->viewToDocument(minViewSize);
161
162 if (qAbs(newWidth) < minDocSize.width()) {
163 newWidth = KisAlgebra2D::signPZ(newWidth) * minDocSize.width();
164 }
165
166 if (qAbs(newHeight) < minDocSize.height()) {
167 newHeight = KisAlgebra2D::signPZ(newHeight) * minDocSize.height();
168 }
169
170 qreal zoomX = qAbs(startWidth) >= minDocSize.width() ? newWidth / startWidth : 1.0;
171 qreal zoomY = qAbs(startHeight) >= minDocSize.height() ? newHeight / startHeight : 1.0;
172
173 if (keepAspect) {
174 const bool cornerUsed = m_bottom + m_top + m_left + m_right == 2;
175 if (cornerUsed) {
176 if (startWidth < startHeight) {
177 zoomY = zoomX;
178 } else {
179 zoomX = zoomY;
180 }
181 } else {
182 if (m_left || m_right) {
183 zoomY = qAbs(zoomX);
184 } else {
185 zoomX = qAbs(zoomY);
186 }
187 }
188 }
189
190 resizeBy(scaleFromCenter ? m_globalCenterPoint : m_globalStillPoint, zoomX, zoomY);
191}
qreal distance(const QPointF &p1, const QPointF &p2)
virtual const KoViewConverter * viewConverter() const =0
bool keepAspectRatio() const
Definition KoShape.cpp:1052
QPointF snap(const QPointF &mousePosition, Qt::KeyboardModifiers modifiers)
snaps the mouse position, returns if mouse was snapped
virtual QPointF viewToDocument(const QPointF &viewPoint) const
void resizeBy(const QPointF &stillPoint, qreal zoomX, qreal zoomY)

References KoToolBase::canvas(), distance(), KoShape::keepAspectRatio(), m_bottom, m_globalCenterPoint, m_globalStillPoint, m_initialSelectionSize, m_left, m_right, m_selectedShapes, m_start, m_top, m_unwindMatrix, resizeBy(), KisAlgebra2D::signPZ(), KoSnapGuide::snap(), KoCanvasBase::snapGuide, KoInteractionStrategy::tool(), KoCanvasBase::viewConverter(), and KoViewConverter::viewToDocument().

◆ paint()

void ShapeResizeStrategy::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 226 of file ShapeResizeStrategy.cpp.

227{
228 Q_UNUSED(painter);
229 Q_UNUSED(converter);
230}

◆ resizeBy()

void ShapeResizeStrategy::resizeBy ( const QPointF & stillPoint,
qreal zoomX,
qreal zoomY )
private

Definition at line 193 of file ShapeResizeStrategy.cpp.

194{
195 if (!m_executedCommand) {
196 const bool usePostScaling = m_selectedShapes.size() > 1 || m_forceUniformScalingMode;
197
198 m_executedCommand.reset(
201 zoomX, zoomY,
202 stillPoint,
203 false, usePostScaling, m_postScalingCoveringTransform));
204 m_executedCommand->redo();
205 } else {
206 m_executedCommand->replaceResizeAction(zoomX, zoomY, stillPoint);
207 }
208}

References m_executedCommand, m_forceUniformScalingMode, m_postScalingCoveringTransform, and m_selectedShapes.

Member Data Documentation

◆ m_bottom

bool ShapeResizeStrategy::m_bottom {false}
private

Definition at line 52 of file ShapeResizeStrategy.h.

52{false};

◆ m_executedCommand

QScopedPointer<KoShapeResizeCommand> ShapeResizeStrategy::m_executedCommand
private

Definition at line 57 of file ShapeResizeStrategy.h.

◆ m_forceUniformScalingMode

bool ShapeResizeStrategy::m_forceUniformScalingMode {false}
private

Definition at line 59 of file ShapeResizeStrategy.h.

59{false};

◆ m_globalCenterPoint

QPointF ShapeResizeStrategy::m_globalCenterPoint
private

Definition at line 56 of file ShapeResizeStrategy.h.

◆ m_globalStillPoint

QPointF ShapeResizeStrategy::m_globalStillPoint
private

Definition at line 55 of file ShapeResizeStrategy.h.

◆ m_initialSelectionSize

QSizeF ShapeResizeStrategy::m_initialSelectionSize
private

Definition at line 48 of file ShapeResizeStrategy.h.

◆ m_left

bool ShapeResizeStrategy::m_left {false}
private

Definition at line 51 of file ShapeResizeStrategy.h.

51{false};

◆ m_postScalingCoveringTransform

QTransform ShapeResizeStrategy::m_postScalingCoveringTransform
private

Definition at line 47 of file ShapeResizeStrategy.h.

◆ m_right

bool ShapeResizeStrategy::m_right {false}
private

Definition at line 53 of file ShapeResizeStrategy.h.

53{false};

◆ m_selectedShapes

QList<KoShape *> ShapeResizeStrategy::m_selectedShapes
private

Definition at line 45 of file ShapeResizeStrategy.h.

◆ m_start

QPointF ShapeResizeStrategy::m_start
private

Definition at line 44 of file ShapeResizeStrategy.h.

◆ m_top

bool ShapeResizeStrategy::m_top {false}
private

Definition at line 50 of file ShapeResizeStrategy.h.

50{false};

◆ m_unwindMatrix

QTransform ShapeResizeStrategy::m_unwindMatrix
private

Definition at line 49 of file ShapeResizeStrategy.h.


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