KQuickImageEditor

resizehandle.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2019 Marco Martin <[email protected]>
3  * SPDX-FileCopyrightText: (C) 2020 Carl Schwan <[email protected]>
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 
14 ResizeHandle::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 
44 QQuickItem *ResizeHandle::rectangle() const
45 {
46  return m_rectangle;
47 }
48 
49 void ResizeHandle::setResizeCorner(ResizeHandle::Corner corner)
50 {
51  if (m_resizeCorner == corner) {
52  return;
53  }
54  m_resizeCorner = corner;
55  Q_EMIT resizeCornerChanged();
56 }
57 
58 void 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 
67 bool ResizeHandle::resizeBlocked() const
68 {
69  return false; // m_resizeWidthBlocked || m_resizeHeightBlocked;
70 }
71 
72 bool ResizeHandle::resizeLeft() const
73 {
74  return m_resizeCorner == Left || m_resizeCorner == TopLeft || m_resizeCorner == BottomLeft;
75 }
76 
77 bool ResizeHandle::resizeTop() const
78 {
79  return m_resizeCorner == Top || m_resizeCorner == TopLeft || m_resizeCorner == TopRight;
80 }
81 
82 bool ResizeHandle::resizeRight() const
83 {
84  return m_resizeCorner == Right || m_resizeCorner == TopRight || m_resizeCorner == BottomRight;
85 }
86 
87 bool ResizeHandle::resizeBottom() const
88 {
89  return m_resizeCorner == Bottom || m_resizeCorner == BottomLeft || m_resizeCorner == BottomRight;
90 }
91 
92 void 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 
104 void 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 
112 void 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 
151 void ResizeHandle::mouseReleaseEvent(QMouseEvent *event)
152 {
153  event->accept();
154 
155  setResizeBlocked(false, false);
156  Q_EMIT resizeBlockedChanged();
157 }
Left
LeftButton
qreal x() const const
qreal y() const const
SizeHorCursor
Right
Top
qreal height() const const
qreal width() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Oct 18 2021 23:08:19 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.