17#include "selectionmanager.h"
20#include "vectorimage.h"
27SelectionManager::SelectionManager(
Editor* editor) :
BaseManager(editor, __FUNCTION__)
31SelectionManager::~SelectionManager()
35bool SelectionManager::init()
42 resetSelectionProperties();
51void SelectionManager::workingLayerChanged(
Layer *)
62 mSelectionTransform.
reset();
65void SelectionManager::resetSelectionTransform()
67 mSelectionTransform.
reset();
70bool SelectionManager::isOutsideSelectionArea(
const QPointF& point)
const
72 return (!mSelectionTransform.
map(mSelectionPolygon).containsPoint(point,
Qt::WindingFill)) && mMoveMode == MoveMode::NONE;
75void SelectionManager::deleteSelection()
77 emit needDeleteSelection();
80qreal SelectionManager::selectionTolerance()
const
82 return qAbs(mSelectionTolerance * editor()->viewScaleInversed());
85QPointF SelectionManager::getSelectionAnchorPoint()
const
88 if (mSelectionPolygon.count() < 3) {
return anchorPoint; }
90 if (mMoveMode == MoveMode::BOTTOMRIGHT)
92 anchorPoint = mSelectionPolygon[0];
94 else if (mMoveMode == MoveMode::BOTTOMLEFT)
96 anchorPoint = mSelectionPolygon[1];
98 else if (mMoveMode == MoveMode::TOPLEFT)
100 anchorPoint = mSelectionPolygon[2];
102 else if (mMoveMode == MoveMode::TOPRIGHT)
104 anchorPoint = mSelectionPolygon[3];
106 anchorPoint =
QLineF(mSelectionPolygon[0], mSelectionPolygon[2]).
pointAt(.5);
114 if (mSelectionPolygon.count() < 4)
116 mMoveMode = MoveMode::NONE;
122 const double calculatedSelectionTol = selectionTolerance();
124 if (
QLineF(point, projectedPolygon[0]).length() < calculatedSelectionTol)
126 mMoveMode = MoveMode::TOPLEFT;
128 else if (
QLineF(point, projectedPolygon[1]).length() < calculatedSelectionTol)
130 mMoveMode = MoveMode::TOPRIGHT;
132 else if (
QLineF(point, projectedPolygon[2]).length() < calculatedSelectionTol)
134 mMoveMode = MoveMode::BOTTOMRIGHT;
136 else if (
QLineF(point, projectedPolygon[3]).length() < calculatedSelectionTol)
138 mMoveMode = MoveMode::BOTTOMLEFT;
142 mMoveMode = MoveMode::MIDDLE;
146 mMoveMode = MoveMode::NONE;
154 case MoveMode::MIDDLE: {
155 QPointF newOffset = currentPoint - mDragOrigin;
160 mTranslation = offset + newOffset;
164 case MoveMode::TOPLEFT:
165 case MoveMode::TOPRIGHT:
166 case MoveMode::BOTTOMRIGHT:
167 case MoveMode::BOTTOMLEFT: {
172 qreal originWidth = mSelectionPolygon[1].x() - mSelectionPolygon[0].x();
173 qreal originHeight = mSelectionPolygon[3].y() - mSelectionPolygon[0].y();
178 if (mMoveMode == MoveMode::TOPLEFT) {
179 movingAnchor =
QVector2D(projectedPolygon[0]);
180 staticXAnchor =
QVector2D(projectedPolygon[1]);
181 staticYAnchor =
QVector2D(projectedPolygon[3]);
182 }
else if (mMoveMode == MoveMode::TOPRIGHT) {
183 movingAnchor =
QVector2D(projectedPolygon[1]);
184 staticXAnchor =
QVector2D(projectedPolygon[0]);
185 staticYAnchor =
QVector2D(projectedPolygon[2]);
186 }
else if (mMoveMode == MoveMode::BOTTOMRIGHT) {
187 movingAnchor =
QVector2D(projectedPolygon[2]);
188 staticXAnchor =
QVector2D(projectedPolygon[3]);
189 staticYAnchor =
QVector2D(projectedPolygon[1]);
191 movingAnchor =
QVector2D(projectedPolygon[3]);
192 staticXAnchor =
QVector2D(projectedPolygon[2]);
193 staticYAnchor =
QVector2D(projectedPolygon[0]);
196 QVector2D directionVecX = staticXAnchor - currentPVec;
197 QVector2D directionVecY = staticYAnchor - currentPVec;
203 qreal scaleX = distanceX / originWidth;
204 qreal scaleY = distanceY / originHeight;
205 if (mAspectRatioFixed) {
209 scale(scaleX, scaleY);
213 case MoveMode::ROTATION: {
214 rotate(rotationOffset, rotationIncrement);
223void SelectionManager::translate(
QPointF newPos)
225 mTranslation += newPos;
228void SelectionManager::rotate(qreal angle, qreal lockedAngle)
230 if (lockedAngle > 0) {
231 mRotatedAngle = constrainRotationToAngle(angle, lockedAngle);
233 mRotatedAngle = angle;
237void SelectionManager::scale(qreal sX, qreal sY)
244 if (qFuzzyIsNull(sX)) {
254 if (qFuzzyIsNull(sY)) {
263int SelectionManager::constrainRotationToAngle(
const qreal rotatedAngle,
const int rotationIncrement)
const
265 return qRound(rotatedAngle / rotationIncrement) * rotationIncrement;
268qreal SelectionManager::angleFromPoint(
const QPointF& point,
const QPointF& anchorPoint)
const
270 return qRadiansToDegrees(MathUtils::getDifferenceAngle(mSelectionTransform.
map(anchorPoint), point));
280 mSelectionPolygon = rect;
281 mOriginalRect = rect;
286 emit selectionChanged();
289void SelectionManager::setTransformAnchor(
const QPointF& point)
295 mTranslation = mTranslation - oldPos + newPos;
296 mAnchorPoint = point;
309 s.
scale(mScaleX, mScaleY);
310 mSelectionTransform = t * s * r * t2;
315 if (qAbs(currentPoint.
y()) > qAbs(currentPoint.
x())) {
317 return QPointF(0, currentPoint.
y());
321 return QPointF(currentPoint.
x(), 0);
338 setTransformAnchor(mOriginalRect.
center());
340 emit selectionChanged();
343void SelectionManager::resetSelectionProperties()
348 mMoveMode = MoveMode::NONE;
349 emit selectionChanged();
void flipSelection(bool flipVertical)
ScribbleArea::flipSelection flip selection along the X or Y axis.
void resetSelectionTransformProperties()
SelectionManager::resetSelectionTransformProperties should be used whenever translate,...
void alignPositionToAxis(bool state)
Locks movement either horizontally or vertically depending on drag direction.
void setMoveModeForAnchorInRange(const QPointF &point)
Checks if the point is over a handle (corner) or body and sets the MoveMode accordingly.
QPointF mapToSelection(const QPointF &point) const
Maps a point from Canvas/Layer space INTO the Selection's transformed space.
void setSelection(QRectF rect, bool roundPixels=false)
Defines the selection area.
void adjustSelection(const QPointF ¤tPoint, const QPointF &offset, qreal rotationOffset, int rotationIncrement=0)
Updates the selection transform (move, scale, rotate) based on input delta.
void calculateSelectionTransformation()
This should be called to update the selection transform.
QPointF pointAt(qreal t) const const
bool containsPoint(const QPointF &point, Qt::FillRule fillRule) const const
QPointF center() const const
QRect toAlignedRect() const const
float dotProduct(const QVector2D &v1, const QVector2D &v2)