1 /* BEGIN_COMMON_COPYRIGHT_HEADER
2 * (c)LGPL2+
3 *
4 * LXQt - a lightweight, Qt based, desktop toolset
5 * https://lxqt.org
6 *
7 * Copyright: 2010-2013 Razor team
8 * Authors:
9 * Kuzma Shapran <kuzma.shapran@gmail.com>
10 *
11 * This program or library is free software; you can redistribute it
12 * and/or modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20
21 * You should have received a copy of the GNU Lesser General
22 * Public License along with this library; if not, write to the
23 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 * Boston, MA 02110-1301 USA
25 *
26 * END_COMMON_COPYRIGHT_HEADER */
27
28
29 #include "lxqtrotatedwidget.h"
30
31 #include <QPainter>
32 #include <QImage>
33
34 #include <QApplication>
35
36 #include <QMouseEvent>
37
38 #ifndef QT_NO_WHEELEVENT
39 #include <QWheelEvent>
40 #endif
41
42 #include <QResizeEvent>
43
44 using namespace LXQt;
45
RotatedWidget(QWidget & content,QWidget * parent,Qt::WindowFlags f)46 RotatedWidget::RotatedWidget(QWidget &content, QWidget *parent, Qt::WindowFlags f)
47 : QWidget(parent, f)
48 , mContent(&content)
49 , mOrigin(Qt::TopLeftCorner)
50 , mTransferMousePressEvent(false)
51 , mTransferMouseReleaseEvent(false)
52 , mTransferMouseDoubleClickEvent(false)
53 , mTransferMouseMoveEvent(false)
54 #ifndef QT_NO_WHEELEVENT
55 , mTransferWheelEvent(false)
56 #endif
57 , mTransferEnterEvent(false)
58 , mTransferLeaveEvent(false)
59 {
60 mContent->setParent(this);
61 }
62
origin() const63 Qt::Corner RotatedWidget::origin() const
64 {
65 return mOrigin;
66 }
67
setOrigin(Qt::Corner newOrigin)68 void RotatedWidget::setOrigin(Qt::Corner newOrigin)
69 {
70 if (mOrigin != newOrigin)
71 {
72 if (mOrigin == Qt::TopLeftCorner)
73 mContent->hide();
74
75 mOrigin = newOrigin;
76 adjustContentSize();
77 update();
78
79 if (mOrigin == Qt::TopLeftCorner)
80 mContent->show();
81 }
82 }
83
content() const84 QWidget * RotatedWidget::content() const
85 {
86 return mContent;
87 }
88
adjustContentSize()89 void RotatedWidget::adjustContentSize()
90 {
91 mContent->adjustSize();
92
93 const QSize before = size();
94
95 adjustSize();
96
97 if (before != size())
98 updateGeometry();
99 }
100
adjustedSize(QSize size) const101 QSize RotatedWidget::adjustedSize(QSize size) const
102 {
103 switch (mOrigin)
104 {
105 case Qt::TopLeftCorner:
106 case Qt::BottomRightCorner:
107 break;
108
109 case Qt::TopRightCorner:
110 case Qt::BottomLeftCorner:
111 size.transpose();
112 break;
113 }
114
115 return size;
116 }
117
adjustedPoint(QPointF point) const118 QPointF RotatedWidget::adjustedPoint(QPointF point) const
119 {
120 switch (mOrigin)
121 {
122 case Qt::TopLeftCorner:
123 case Qt::BottomRightCorner:
124 break;
125
126 case Qt::TopRightCorner:
127 case Qt::BottomLeftCorner:
128 point = QPointF(point.y(), point.x());
129 break;
130 }
131
132 return point;
133 }
134
minimumSizeHint() const135 QSize RotatedWidget::minimumSizeHint() const
136 {
137 return adjustedSize(mContent->minimumSizeHint());
138 }
139
sizeHint() const140 QSize RotatedWidget::sizeHint() const
141 {
142 return adjustedSize(mContent->sizeHint());
143 }
144
paintEvent(QPaintEvent *)145 void RotatedWidget::paintEvent(QPaintEvent */*event*/)
146 {
147 if (mOrigin == Qt::TopLeftCorner)
148 return;
149
150 const QSize sz = mContent->size();
151
152 QPainter painter(this);
153
154 QTransform transform;
155 QPoint originPoint;
156 switch (mOrigin)
157 {
158 case Qt::TopLeftCorner:
159 // transform.rotate(0.0);
160 // originPoint = QPoint(0.0, 0.0);
161 break;
162
163 case Qt::TopRightCorner:
164 transform.rotate(90.0);
165 originPoint = QPoint(0.0, -sz.height());
166 break;
167
168 case Qt::BottomRightCorner:
169 transform.rotate(180.0);
170 originPoint = QPoint(-sz.width(), -sz.height());
171 break;
172
173 case Qt::BottomLeftCorner:
174 transform.rotate(270.0);
175 originPoint = QPoint(-sz.width(), 0.0);
176 break;
177 }
178 painter.setTransform(transform);
179 mContent->render(&painter, originPoint, QRegion(), RenderFlags(DrawChildren));
180 }
181
mousePressEvent(QMouseEvent * event)182 void RotatedWidget::mousePressEvent(QMouseEvent *event)
183 {
184 if (!mTransferMousePressEvent)
185 {
186 event->ignore();
187 return;
188 }
189
190 static bool cascadeCall = false;
191 if (cascadeCall)
192 return;
193 cascadeCall = true;
194
195 QMouseEvent contentEvent(event->type(), adjustedPoint(event->pos()), event->globalPos(), event->button(), event->buttons(), event->modifiers());
196 QApplication::sendEvent(mContent, &contentEvent);
197
198 cascadeCall = false;
199 }
200
mouseReleaseEvent(QMouseEvent * event)201 void RotatedWidget::mouseReleaseEvent(QMouseEvent *event)
202 {
203 if (!mTransferMouseReleaseEvent)
204 {
205 event->ignore();
206 return;
207 }
208
209 static bool cascadeCall = false;
210 if (cascadeCall)
211 return;
212 cascadeCall = true;
213
214 QMouseEvent contentEvent(event->type(), adjustedPoint(event->pos()), event->globalPos(), event->button(), event->buttons(), event->modifiers());
215 QApplication::sendEvent(mContent, &contentEvent);
216
217 cascadeCall = false;
218 }
219
mouseDoubleClickEvent(QMouseEvent * event)220 void RotatedWidget::mouseDoubleClickEvent(QMouseEvent *event)
221 {
222 if (!mTransferMouseDoubleClickEvent)
223 {
224 event->ignore();
225 return;
226 }
227
228 static bool cascadeCall = false;
229 if (cascadeCall)
230 return;
231 cascadeCall = true;
232
233 QMouseEvent contentEvent(event->type(), adjustedPoint(event->pos()), event->globalPos(), event->button(), event->buttons(), event->modifiers());
234 QApplication::sendEvent(mContent, &contentEvent);
235
236 cascadeCall = false;
237 }
238
mouseMoveEvent(QMouseEvent * event)239 void RotatedWidget::mouseMoveEvent(QMouseEvent *event)
240 {
241 if (!mTransferMouseMoveEvent)
242 {
243 event->ignore();
244 return;
245 }
246
247 static bool cascadeCall = false;
248 if (cascadeCall)
249 return;
250 cascadeCall = true;
251
252 QMouseEvent contentEvent(event->type(), adjustedPoint(event->pos()), event->globalPos(), event->button(), event->buttons(), event->modifiers());
253 QApplication::sendEvent(mContent, &contentEvent);
254
255 cascadeCall = false;
256 }
257
258 #ifndef QT_NO_WHEELEVENT
wheelEvent(QWheelEvent * event)259 void RotatedWidget::wheelEvent(QWheelEvent *event)
260 {
261 if (!mTransferWheelEvent)
262 {
263 event->ignore();
264 return;
265 }
266
267 static bool cascadeCall = false;
268 if (cascadeCall)
269 return;
270 cascadeCall = true;
271
272 QWheelEvent contentEvent(adjustedPoint(event->position()), event->globalPosition(), event->pixelDelta(), event->angleDelta(), event->buttons(), event->modifiers(), event->phase(), false);
273 QApplication::sendEvent(mContent, &contentEvent);
274
275 cascadeCall = false;
276 }
277 #endif
278
enterEvent(QEvent * event)279 void RotatedWidget::enterEvent(QEvent *event)
280 {
281 if (!mTransferEnterEvent)
282 {
283 event->ignore();
284 return;
285 }
286
287 static bool cascadeCall = false;
288 if (cascadeCall)
289 return;
290 cascadeCall = true;
291
292 QApplication::sendEvent(mContent, event);
293
294 cascadeCall = false;
295 }
296
leaveEvent(QEvent * event)297 void RotatedWidget::leaveEvent(QEvent *event)
298 {
299 if (!mTransferLeaveEvent)
300 {
301 event->ignore();
302 return;
303 }
304
305 static bool cascadeCall = false;
306 if (cascadeCall)
307 return;
308 cascadeCall = true;
309
310 QApplication::sendEvent(mContent, event);
311
312 cascadeCall = false;
313 }
314
resizeEvent(QResizeEvent * event)315 void RotatedWidget::resizeEvent(QResizeEvent *event)
316 {
317 static bool cascadeCall = false;
318 if (cascadeCall)
319 return;
320 cascadeCall = true;
321
322 QResizeEvent contentEvent(adjustedSize(event->size()), adjustedSize(event->oldSize()));
323 QApplication::sendEvent(mContent, &contentEvent);
324
325 cascadeCall = false;
326 }
327