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

#include <kis_constrained_rect.h>

+ Inheritance diagram for KisConstrainedRect:

Public Types

enum  HandleType {
  None = 0 , UpperLeft , UpperRight , LowerLeft ,
  LowerRight , Upper , Lower , Left ,
  Right , Inside , Creation
}
 

Signals

void sigLockValuesChanged ()
 
void sigValuesChanged ()
 

Public Member Functions

bool canGrow () const
 
bool centered () const
 
QPointF handleSnapPoint (HandleType handle, const QPointF &cursorPos)
 
bool heightLocked () const
 
 KisConstrainedRect ()
 
void moveHandle (HandleType handle, const QPoint &offset, const QRect &oldRect)
 
void normalize ()
 
qreal ratio () const
 
bool ratioLocked () const
 
QRect rect () const
 
void setCanGrow (bool value)
 
void setCentered (bool value)
 
void setCropRect (const QRect &cropRect)
 
void setHeight (int value)
 
void setHeightLocked (bool value)
 
void setOffset (const QPoint &offset)
 
void setRatio (qreal value)
 
void setRatioLocked (bool value)
 
void setRectInitial (const QRect &rect)
 
void setWidth (int value)
 
void setWidthLocked (bool value)
 
bool widthLocked () const
 
 ~KisConstrainedRect () override
 

Private Member Functions

void assignNewSize (const QSize &newSize)
 
int heightFromWidthUnsignedRatio (int width, qreal ratio, int oldHeight) const
 
void storeRatioSafe (const QSize &newSize)
 
int widthFromHeightUnsignedRatio (int height, qreal ratio, int oldWidth) const
 

Private Attributes

bool m_canGrow {true}
 
bool m_centered {false}
 
QRect m_cropRect
 
bool m_heightLocked {false}
 
qreal m_ratio {1.0}
 
bool m_ratioLocked {false}
 
QRect m_rect
 
bool m_widthLocked {false}
 

Detailed Description

Definition at line 15 of file kis_constrained_rect.h.

Member Enumeration Documentation

◆ HandleType

Constructor & Destructor Documentation

◆ KisConstrainedRect()

KisConstrainedRect::KisConstrainedRect ( )

Definition at line 14 of file kis_constrained_rect.cpp.

15{
16}

◆ ~KisConstrainedRect()

KisConstrainedRect::~KisConstrainedRect ( )
override

Definition at line 18 of file kis_constrained_rect.cpp.

19{
20}

Member Function Documentation

◆ assignNewSize()

void KisConstrainedRect::assignNewSize ( const QSize & newSize)
private

Definition at line 361 of file kis_constrained_rect.cpp.

362{
363 if (!m_centered) {
364 m_rect.setSize(newSize);
365 } else {
366 QSize sizeDiff = newSize - m_rect.size();
367 m_rect.translate(-qRound(sizeDiff.width() / 2.0), -qRound(sizeDiff.height() / 2.0));
368 m_rect.setSize(newSize);
369 }
370
371 if (!m_canGrow) {
373 }
374
375 Q_EMIT sigValuesChanged();
376}

References m_canGrow, m_centered, m_cropRect, m_rect, and sigValuesChanged().

◆ canGrow()

bool KisConstrainedRect::canGrow ( ) const

Definition at line 43 of file kis_constrained_rect.cpp.

43 {
44 return m_canGrow;
45}

References m_canGrow.

◆ centered()

bool KisConstrainedRect::centered ( ) const

Definition at line 36 of file kis_constrained_rect.cpp.

36 {
37 return m_centered;
38}

References m_centered.

◆ handleSnapPoint()

QPointF KisConstrainedRect::handleSnapPoint ( HandleType handle,
const QPointF & cursorPos )

Definition at line 231 of file kis_constrained_rect.cpp.

232{
233 QPointF snapPoint = cursorPos;
234
235 switch (handle) {
236 case UpperLeft:
237 snapPoint = m_rect.topLeft();
238 break;
239 case UpperRight:
240 snapPoint = m_rect.topRight() + QPointF(1, 0);
241 break;
242 case Creation:
243 break;
244 case LowerRight:
245 snapPoint = m_rect.bottomRight() + QPointF(1, 1);
246 break;
247 case LowerLeft:
248 snapPoint = m_rect.bottomLeft() + QPointF(0, 1);
249 break;
250 case Upper:
251 snapPoint.ry() = m_rect.y();
252 break;
253 case Right:
254 snapPoint.rx() = m_rect.right() + 1;
255 break;
256 case Lower:
257 snapPoint.ry() = m_rect.bottom() + 1;
258 break;
259 case Left:
260 snapPoint.rx() = m_rect.x();
261 break;
262 case Inside:
263 break;
264 case None: // should never happen
265 break;
266 }
267
268 return snapPoint;
269}

References Creation, Inside, Left, Lower, LowerLeft, LowerRight, m_rect, None, Right, Upper, UpperLeft, and UpperRight.

◆ heightFromWidthUnsignedRatio()

int KisConstrainedRect::heightFromWidthUnsignedRatio ( int width,
qreal ratio,
int oldHeight ) const
private

Definition at line 389 of file kis_constrained_rect.cpp.

390{
391 int newHeight = qRound(width / ratio);
392 return KisAlgebra2D::copysign(newHeight, oldHeight);
393}
T copysign(T x, T y)

References KisAlgebra2D::copysign(), and ratio().

◆ heightLocked()

bool KisConstrainedRect::heightLocked ( ) const

Definition at line 398 of file kis_constrained_rect.cpp.

398 {
399 return m_heightLocked;
400}

References m_heightLocked.

◆ moveHandle()

void KisConstrainedRect::moveHandle ( HandleType handle,
const QPoint & offset,
const QRect & oldRect )

Definition at line 58 of file kis_constrained_rect.cpp.

59{
60 const QSize oldSize = oldRect.size();
61 QSize newSize = oldSize;
62 QPoint newOffset = oldRect.topLeft();
63
64 int xSizeCoeff = 1;
65 int ySizeCoeff = 1;
66
67 qreal xOffsetFromSizeChange = 1.0;
68 qreal yOffsetFromSizeChange = 1.0;
69
70 int baseSizeCoeff = 1;
71
72 bool useMoveOnly = false;
73
74 switch (handle) {
75 case UpperLeft:
76 xSizeCoeff = -1;
77 ySizeCoeff = -1;
78 xOffsetFromSizeChange = -1.0;
79 yOffsetFromSizeChange = -1.0;
80 break;
81 case UpperRight:
82 xSizeCoeff = 1;
83 ySizeCoeff = -1;
84 xOffsetFromSizeChange = 0.0;
85 yOffsetFromSizeChange = -1.0;
86 break;
87 case Creation:
88 baseSizeCoeff = 0;
89 Q_FALLTHROUGH();
90 case LowerRight:
91 xSizeCoeff = 1;
92 ySizeCoeff = 1;
93 xOffsetFromSizeChange = 0.0;
94 yOffsetFromSizeChange = 0.0;
95 break;
96 case LowerLeft:
97 xSizeCoeff = -1;
98 ySizeCoeff = 1;
99 xOffsetFromSizeChange = -1.0;
100 yOffsetFromSizeChange = 0.0;
101 break;
102 case Upper:
103 xSizeCoeff = 0;
104 ySizeCoeff = -1;
105 xOffsetFromSizeChange = -0.5;
106 yOffsetFromSizeChange = -1.0;
107 break;
108 case Right:
109 xSizeCoeff = 1;
110 ySizeCoeff = 0;
111 xOffsetFromSizeChange = 0.0;
112 yOffsetFromSizeChange = -0.5;
113 break;
114 case Lower:
115 xSizeCoeff = 0;
116 ySizeCoeff = 1;
117 xOffsetFromSizeChange = -0.5;
118 yOffsetFromSizeChange = 0.0;
119 break;
120 case Left:
121 xSizeCoeff = -1;
122 ySizeCoeff = 0;
123 xOffsetFromSizeChange = -1.0;
124 yOffsetFromSizeChange = -0.5;
125 break;
126 case Inside:
127 useMoveOnly = true;
128 break;
129 case None: // should never happen
130 break;
131 }
132
133 if (!useMoveOnly) {
134 const int centeringSizeCoeff = m_centered ? 2 : 1;
135 if (m_centered) {
136 xOffsetFromSizeChange = -0.5;
137 yOffsetFromSizeChange = -0.5;
138 }
139
140
141 QSize sizeDiff(offset.x() * xSizeCoeff * centeringSizeCoeff,
142 offset.y() * ySizeCoeff * centeringSizeCoeff);
143
144 QSize tempSize = baseSizeCoeff * oldSize + sizeDiff;
145 bool widthPreferable = qAbs(tempSize.width()) > qAbs(tempSize.height() * m_ratio);
146
147 if (ratioLocked()) {
148 if ((widthPreferable && xSizeCoeff != 0) || ySizeCoeff == 0) {
149 newSize.setWidth(tempSize.width());
150 newSize.setHeight(heightFromWidthUnsignedRatio(newSize.width(), m_ratio, tempSize.height()));
151 } else if ((!widthPreferable && ySizeCoeff != 0) || xSizeCoeff == 0) {
152 newSize.setHeight(tempSize.height());
153 newSize.setWidth(widthFromHeightUnsignedRatio(newSize.height(), m_ratio, tempSize.width()));
154 }
155
156 // see https://bugs.kde.org/show_bug.cgi?id=432036
157 if (!m_canGrow && qAbs(newSize.width()) > m_cropRect.width()) {
158 newSize.setWidth(m_cropRect.width());
159 newSize.setHeight(heightFromWidthUnsignedRatio(newSize.width(), m_ratio, newSize.height()));
160 }
161 if (!m_canGrow && qAbs(newSize.height()) > m_cropRect.height()) {
162 newSize.setHeight(m_cropRect.height());
163 newSize.setWidth(widthFromHeightUnsignedRatio(newSize.height(), m_ratio, newSize.width()));
164 }
165 } else if (widthLocked() && heightLocked()) {
166 newSize.setWidth(KisAlgebra2D::copysign(newSize.width(), tempSize.width()));
167 newSize.setHeight(KisAlgebra2D::copysign(newSize.height(), tempSize.height()));
168 } else if (widthLocked()) {
169 newSize.setWidth(KisAlgebra2D::copysign(newSize.width(), tempSize.width()));
170 newSize.setHeight(tempSize.height());
171 storeRatioSafe(newSize);
172 } else if (heightLocked()) {
173 newSize.setHeight(KisAlgebra2D::copysign(newSize.height(), tempSize.height()));
174 newSize.setWidth(tempSize.width());
175 storeRatioSafe(newSize);
176 } else {
177 newSize = baseSizeCoeff * oldSize + sizeDiff;
178 storeRatioSafe(newSize);
179 }
180
181 QSize realSizeDiff = newSize - baseSizeCoeff * oldSize;
182 QPoint offsetDiff(realSizeDiff.width() * xOffsetFromSizeChange,
183 realSizeDiff.height() * yOffsetFromSizeChange);
184
185 newOffset = oldRect.topLeft() + offsetDiff;
186 } else {
187 newOffset = oldRect.topLeft() + offset;
188 }
189
190 QPoint prevOffset = newOffset;
191
192 if (!m_canGrow) {
193 if (newOffset.x() + newSize.width() > m_cropRect.width()) {
194 newOffset.setX(m_cropRect.width() - newSize.width());
195 }
196
197 if (newOffset.y() + newSize.height() > m_cropRect.height()) {
198 newOffset.setY(m_cropRect.height() - newSize.height());
199 }
200 if (newOffset.x() < m_cropRect.x()) {
201 newOffset.setX(m_cropRect.x());
202 }
203 if (newOffset.y() < m_cropRect.y()) {
204 newOffset.setY(m_cropRect.y());
205 }
206 }
207
208 if (!m_ratioLocked && !useMoveOnly) {
209 newOffset = prevOffset;
210 }
211
212 m_rect = QRect(newOffset, newSize);
213
214 if (!m_canGrow) {
216
217 if (ratioLocked() && m_rect.height()) {
218 qreal newRatio = m_rect.width() / (qreal)(m_rect.height());
219
220 if (newRatio > m_ratio) {
221 m_rect.setWidth(widthFromHeightUnsignedRatio(m_rect.height(), m_ratio, m_rect.width()));
222 } else {
223 m_rect.setHeight(heightFromWidthUnsignedRatio(m_rect.width(), m_ratio, m_rect.height()));
224 }
225 }
226 }
227
228 Q_EMIT sigValuesChanged();
229}
void storeRatioSafe(const QSize &newSize)
int widthFromHeightUnsignedRatio(int height, qreal ratio, int oldWidth) const
int heightFromWidthUnsignedRatio(int width, qreal ratio, int oldHeight) const

References KisAlgebra2D::copysign(), Creation, heightFromWidthUnsignedRatio(), heightLocked(), Inside, Left, Lower, LowerLeft, LowerRight, m_canGrow, m_centered, m_cropRect, m_ratio, m_ratioLocked, m_rect, None, ratioLocked(), Right, sigValuesChanged(), storeRatioSafe(), Upper, UpperLeft, UpperRight, widthFromHeightUnsignedRatio(), and widthLocked().

◆ normalize()

void KisConstrainedRect::normalize ( )

Definition at line 271 of file kis_constrained_rect.cpp.

272{
273 setRectInitial(m_rect.normalized());
274}
void setRectInitial(const QRect &rect)

References m_rect, and setRectInitial().

◆ ratio()

qreal KisConstrainedRect::ratio ( ) const

Definition at line 54 of file kis_constrained_rect.cpp.

54 {
55 return qAbs(m_ratio);
56}

References m_ratio.

◆ ratioLocked()

bool KisConstrainedRect::ratioLocked ( ) const

Definition at line 401 of file kis_constrained_rect.cpp.

401 {
402 return m_ratioLocked;
403}

References m_ratioLocked.

◆ rect()

QRect KisConstrainedRect::rect ( ) const

Definition at line 50 of file kis_constrained_rect.cpp.

50 {
51 return m_rect.normalized();
52}

References m_rect.

◆ setCanGrow()

void KisConstrainedRect::setCanGrow ( bool value)

Definition at line 46 of file kis_constrained_rect.cpp.

46 {
48}
float value(const T *src, size_t ch)

References m_canGrow, and value().

◆ setCentered()

void KisConstrainedRect::setCentered ( bool value)

Definition at line 39 of file kis_constrained_rect.cpp.

39 {
41}

References m_centered, and value().

◆ setCropRect()

void KisConstrainedRect::setCropRect ( const QRect & cropRect)

Definition at line 31 of file kis_constrained_rect.cpp.

32{
33 m_cropRect = cropRect;
34}

References m_cropRect.

◆ setHeight()

void KisConstrainedRect::setHeight ( int value)

Definition at line 343 of file kis_constrained_rect.cpp.

344{
346
347 const QSize oldSize = m_rect.size();
348 QSize newSize = oldSize;
349
350 if (ratioLocked()) {
351 newSize.setHeight(value);
352 newSize.setWidth(newSize.height() * m_ratio);
353 } else {
354 newSize.setHeight(value);
355 storeRatioSafe(newSize);
356 }
357
358 assignNewSize(newSize);
359}
void assignNewSize(const QSize &newSize)
#define KIS_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:75

References assignNewSize(), KIS_ASSERT_RECOVER_RETURN, m_ratio, m_rect, ratioLocked(), storeRatioSafe(), and value().

◆ setHeightLocked()

void KisConstrainedRect::setHeightLocked ( bool value)

◆ setOffset()

void KisConstrainedRect::setOffset ( const QPoint & offset)

Definition at line 276 of file kis_constrained_rect.cpp.

277{
278 QRect newRect = m_rect;
279 newRect.moveTo(offset);
280
281 if (!m_canGrow) {
282 newRect &= m_cropRect;
283 }
284
285 if (!newRect.isEmpty()) {
286 m_rect = newRect;
287 }
288
289 Q_EMIT sigValuesChanged();
290}

References m_canGrow, m_cropRect, m_rect, and sigValuesChanged().

◆ setRatio()

void KisConstrainedRect::setRatio ( qreal value)

Definition at line 292 of file kis_constrained_rect.cpp.

292 {
294
295 const qreal eps = 1e-7;
296 const qreal invEps = 1.0 / eps;
297
298 if (value < eps || value > invEps) {
299 Q_EMIT sigValuesChanged();
300 return;
301 }
302
303 const QSize oldSize = m_rect.size();
304 QSize newSize = oldSize;
305
306 if (widthLocked() && heightLocked()) {
307 setHeightLocked(false);
308 }
309
310 m_ratio = value;
311
312 if (!widthLocked() && !heightLocked()) {
313 int area = oldSize.width() * oldSize.height();
314 newSize.setWidth(qRound(std::sqrt(area * m_ratio)));
315 newSize.setHeight(qRound(newSize.width() / m_ratio));
316 } else if (widthLocked()) {
317 newSize.setHeight(newSize.width() / m_ratio);
318 } else if (heightLocked()) {
319 newSize.setWidth(newSize.height() * m_ratio);
320 }
321
322 assignNewSize(newSize);
323}
void setHeightLocked(bool value)
const qreal eps

References assignNewSize(), eps, heightLocked(), KIS_ASSERT_RECOVER_RETURN, m_ratio, m_rect, setHeightLocked(), sigValuesChanged(), value(), and widthLocked().

◆ setRatioLocked()

void KisConstrainedRect::setRatioLocked ( bool value)

◆ setRectInitial()

void KisConstrainedRect::setRectInitial ( const QRect & rect)

Definition at line 22 of file kis_constrained_rect.cpp.

23{
24 m_rect = rect;
25 if (!ratioLocked()) {
26 storeRatioSafe(m_rect.size());
27 }
28 Q_EMIT sigValuesChanged();
29}

References m_rect, ratioLocked(), rect(), sigValuesChanged(), and storeRatioSafe().

◆ setWidth()

void KisConstrainedRect::setWidth ( int value)

Definition at line 325 of file kis_constrained_rect.cpp.

326{
328
329 const QSize oldSize = m_rect.size();
330 QSize newSize = oldSize;
331
332 if (ratioLocked()) {
333 newSize.setWidth(value);
334 newSize.setHeight(newSize.width() / m_ratio);
335 } else {
336 newSize.setWidth(value);
337 storeRatioSafe(newSize);
338 }
339
340 assignNewSize(newSize);
341}

References assignNewSize(), KIS_ASSERT_RECOVER_RETURN, m_ratio, m_rect, ratioLocked(), storeRatioSafe(), and value().

◆ setWidthLocked()

void KisConstrainedRect::setWidthLocked ( bool value)

◆ sigLockValuesChanged

void KisConstrainedRect::sigLockValuesChanged ( )
signal

◆ sigValuesChanged

void KisConstrainedRect::sigValuesChanged ( )
signal

◆ storeRatioSafe()

void KisConstrainedRect::storeRatioSafe ( const QSize & newSize)
private

Definition at line 378 of file kis_constrained_rect.cpp.

379{
380 m_ratio = qAbs(qreal(newSize.width()) / newSize.height());
381}

References m_ratio.

◆ widthFromHeightUnsignedRatio()

int KisConstrainedRect::widthFromHeightUnsignedRatio ( int height,
qreal ratio,
int oldWidth ) const
private

Definition at line 383 of file kis_constrained_rect.cpp.

384{
385 int newWidth = qRound(height * ratio);
386 return KisAlgebra2D::copysign(newWidth, oldWidth);
387}

References KisAlgebra2D::copysign(), and ratio().

◆ widthLocked()

bool KisConstrainedRect::widthLocked ( ) const

Definition at line 395 of file kis_constrained_rect.cpp.

395 {
396 return m_widthLocked;
397}

References m_widthLocked.

Member Data Documentation

◆ m_canGrow

bool KisConstrainedRect::m_canGrow {true}
private

Definition at line 83 of file kis_constrained_rect.h.

83{true};

◆ m_centered

bool KisConstrainedRect::m_centered {false}
private

Definition at line 82 of file kis_constrained_rect.h.

82{false};

◆ m_cropRect

QRect KisConstrainedRect::m_cropRect
private

Definition at line 91 of file kis_constrained_rect.h.

◆ m_heightLocked

bool KisConstrainedRect::m_heightLocked {false}
private

Definition at line 88 of file kis_constrained_rect.h.

88{false};

◆ m_ratio

qreal KisConstrainedRect::m_ratio {1.0}
private

Definition at line 85 of file kis_constrained_rect.h.

85{1.0};

◆ m_ratioLocked

bool KisConstrainedRect::m_ratioLocked {false}
private

Definition at line 89 of file kis_constrained_rect.h.

89{false};

◆ m_rect

QRect KisConstrainedRect::m_rect
private

Definition at line 84 of file kis_constrained_rect.h.

◆ m_widthLocked

bool KisConstrainedRect::m_widthLocked {false}
private

Definition at line 87 of file kis_constrained_rect.h.

87{false};

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