KQuickImageEditor

resizehandle.cpp
1/*
2 * SPDX-FileCopyrightText: (C) 2019 Marco Martin <mart@kde.org>
3 * SPDX-FileCopyrightText: (C) 2020 Carl Schwan <carl@carlschwan.eu>
4 *
5 * SPDX-License-Identifier: LGPL-2.1-or-later
6 */
7
8#include "resizehandle.h"
9#include "resizerectangle.h"
10
11#include <QCursor>
12#include <cmath>
13
14ResizeHandle::ResizeHandle(QQuickItem *parent)
15 : QQuickItem(parent)
16{
17 setAcceptedMouseButtons(Qt::LeftButton);
18
19 auto syncCursor = [this]() {
20 switch (m_resizeCorner) {
21 case Left:
22 case Right:
23 setCursor(QCursor(Qt::SizeHorCursor));
24 break;
25 case Top:
26 case Bottom:
27 setCursor(QCursor(Qt::SizeVerCursor));
28 break;
29 case TopLeft:
30 case BottomRight:
31 setCursor(QCursor(Qt::SizeFDiagCursor));
32 break;
33 case TopRight:
34 case BottomLeft:
35 default:
36 setCursor(Qt::SizeBDiagCursor);
37 }
38 };
39
40 syncCursor();
41 connect(this, &ResizeHandle::resizeCornerChanged, this, syncCursor);
42}
43
44QQuickItem *ResizeHandle::rectangle() const
45{
46 return m_rectangle;
47}
48
49void ResizeHandle::setResizeCorner(ResizeHandle::Corner corner)
50{
51 if (m_resizeCorner == corner) {
52 return;
53 }
54 m_resizeCorner = corner;
55 Q_EMIT resizeCornerChanged();
56}
57
58void ResizeHandle::setRectangle(QQuickItem *rectangle)
59{
60 if (m_rectangle == rectangle) {
61 return;
62 }
63 m_rectangle = qobject_cast<ResizeRectangle *>(rectangle);
64 Q_EMIT rectangleChanged();
65}
66
67bool ResizeHandle::resizeBlocked() const
68{
69 return false; // m_resizeWidthBlocked || m_resizeHeightBlocked;
70}
71
72bool ResizeHandle::resizeLeft() const
73{
74 return m_resizeCorner == Left || m_resizeCorner == TopLeft || m_resizeCorner == BottomLeft;
75}
76
77bool ResizeHandle::resizeTop() const
78{
79 return m_resizeCorner == Top || m_resizeCorner == TopLeft || m_resizeCorner == TopRight;
80}
81
82bool ResizeHandle::resizeRight() const
83{
84 return m_resizeCorner == Right || m_resizeCorner == TopRight || m_resizeCorner == BottomRight;
85}
86
87bool ResizeHandle::resizeBottom() const
88{
89 return m_resizeCorner == Bottom || m_resizeCorner == BottomLeft || m_resizeCorner == BottomRight;
90}
91
92void ResizeHandle::setResizeBlocked(bool width, bool height)
93{
94 if (m_resizeWidthBlocked == width && m_resizeHeightBlocked == height) {
95 return;
96 }
97
98 m_resizeWidthBlocked = width;
99 m_resizeHeightBlocked = height;
100
101 Q_EMIT resizeBlockedChanged();
102}
103
104void ResizeHandle::mousePressEvent(QMouseEvent *event)
105{
106 m_mouseDownPosition = event->windowPos();
107 m_mouseDownGeometry = QRectF(m_rectangle->insideX(), m_rectangle->insideY(), m_rectangle->insideWidth(), m_rectangle->insideHeight());
108 setResizeBlocked(false, false);
109 event->accept();
110}
111
112void ResizeHandle::mouseMoveEvent(QMouseEvent *event)
113{
114 const QPointF difference = m_mouseDownPosition - event->windowPos();
115
116 const QSizeF minimumSize = QSize(20, 20);
117
118 // Horizontal resize
119 if (resizeLeft()) {
120 const qreal width = qMax(minimumSize.width(), m_mouseDownGeometry.width() + difference.x());
121 const qreal x = m_mouseDownGeometry.x() + (m_mouseDownGeometry.width() - width);
122
123 m_rectangle->setInsideX(x);
124 m_rectangle->setInsideWidth(width);
125 setResizeBlocked(m_mouseDownGeometry.width() + difference.x() < minimumSize.width(), m_resizeHeightBlocked);
126 } else if (resizeRight()) {
127 const qreal width = qMax(minimumSize.width(), m_mouseDownGeometry.width() - difference.x());
128
129 m_rectangle->setInsideWidth(width);
130 setResizeBlocked(m_mouseDownGeometry.width() - difference.x() < minimumSize.width(), m_resizeHeightBlocked);
131 }
132
133 // Vertical Resize
134 if (resizeTop()) {
135 const qreal height = qMax(minimumSize.height(), m_mouseDownGeometry.height() + difference.y());
136 const qreal y = m_mouseDownGeometry.y() + (m_mouseDownGeometry.height() - height);
137
138 m_rectangle->setInsideY(y);
139 m_rectangle->setInsideHeight(height);
140 setResizeBlocked(m_resizeWidthBlocked, m_mouseDownGeometry.height() + difference.y() < minimumSize.height());
141 } else if (resizeBottom()) {
142 const qreal height = qMax(minimumSize.height(), m_mouseDownGeometry.height() - difference.y());
143
144 m_rectangle->setInsideHeight(qMax(height, minimumSize.height()));
145 setResizeBlocked(m_resizeWidthBlocked, m_mouseDownGeometry.height() - difference.y() < minimumSize.height());
146 }
147
148 event->accept();
149}
150
151void ResizeHandle::mouseReleaseEvent(QMouseEvent *event)
152{
153 event->accept();
154
155 setResizeBlocked(false, false);
156 Q_EMIT resizeBlockedChanged();
157}
158
159#include "moc_resizehandle.cpp"
Q_EMITQ_EMIT
T qobject_cast(QObject *object)
qreal x() const const
qreal y() const const
qreal height() const const
qreal width() const const
qreal x() const const
qreal y() const const
qreal height() const const
qreal width() const const
SizeHorCursor
LeftButton
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:17:26 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.