| 7 | namespace geometry |
| 8 | { |
| 9 | QPoint cornerAtPoint(const QPoint &corner, const QSize &size, |
| 10 | const QRect &boundRect) |
| 11 | { |
| 12 | auto clamped = corner; |
| 13 | if (!boundRect.contains(clamped)) { |
| 14 | const auto x = std::clamp(clamped.x(), boundRect.left(), boundRect.right()); |
| 15 | const auto y = std::clamp(clamped.y(), boundRect.top(), boundRect.bottom()); |
| 16 | clamped = QPoint(x, y); |
| 17 | } |
| 18 | |
| 19 | const auto zeroCorner = clamped - boundRect.topLeft(); |
| 20 | const auto boundWidth = boundRect.width(); |
| 21 | const auto boundHeight = boundRect.height(); |
| 22 | |
| 23 | QPoint result; |
| 24 | if (boundWidth <= size.width()) { // not fits |
| 25 | result.rx() = 0; |
| 26 | } else if (boundWidth - zeroCorner.x() >= size.width()) { // enough on right |
| 27 | result.rx() = zeroCorner.x(); |
| 28 | } else if (zeroCorner.x() >= size.width()) { // enough on left |
| 29 | result.rx() = zeroCorner.x() - size.width() + 1; |
| 30 | } else { // not enough on both sides |
| 31 | result.rx() = |
| 32 | zeroCorner.x() >= boundWidth / 2 ? 0 : boundWidth - size.width() + 1; |
| 33 | } |
| 34 | |
| 35 | if (boundHeight <= size.height()) { |
| 36 | result.ry() = 0; |
| 37 | } else if (boundHeight - zeroCorner.y() >= size.height()) { |
| 38 | result.ry() = zeroCorner.y(); |
| 39 | } else if (zeroCorner.y() >= size.height()) { |
| 40 | result.ry() = zeroCorner.y() - size.height() + 1; |
| 41 | } else { |
| 42 | result.ry() = |
| 43 | zeroCorner.y() >= boundHeight / 2 ? 0 : boundHeight - size.height() + 1; |
| 44 | } |
| 45 | |
| 46 | return result + boundRect.topLeft(); |
| 47 | } |
| 48 | |
| 49 | } // namespace geometry |
| 50 | } // namespace service |