1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the widgets module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#include "qwidgetresizehandler_p.h"
31
#ifndef QT_NO_RESIZEHANDLER
33
#include "qapplication.h"
34
#include "qdesktopwidget.h"
36
#include "qsizegrip.h"
39
#include "qt_windows.h"
45
static bool resizeHorizontalDirectionFixed = false;
46
static bool resizeVerticalDirectionFixed = false;
48
QWidgetResizeHandler::QWidgetResizeHandler(QWidget *parent, QWidget *cw)
49
: QObject(parent), widget(parent), childWidget(cw ? cw : parent),
50
fw(0), extrahei(0), buttonDown(false), moveResizeMode(false), sizeprotect(true), movingEnabled(true)
53
widget->setMouseTracking(true);
54
QFrame *frame = qobject_cast<QFrame*>(widget);
55
range = frame ? frame->frameWidth() : RANGE;
56
range = qMax(RANGE, range);
57
activeForMove = activeForResize = true;
58
widget->installEventFilter(this);
61
void QWidgetResizeHandler::setActive(Action ac, bool b)
69
setMouseCursor(Nowhere);
72
bool QWidgetResizeHandler::isActive(Action ac) const
75
if (ac & Move) b = activeForMove;
76
if (ac & Resize) b |= activeForResize;
81
bool QWidgetResizeHandler::eventFilter(QObject *o, QEvent *ee)
83
if (!isActive() || !ee->spontaneous())
86
if (ee->type() != QEvent::MouseButtonPress &&
87
ee->type() != QEvent::MouseButtonRelease &&
88
ee->type() != QEvent::MouseMove &&
89
ee->type() != QEvent::KeyPress &&
90
ee->type() != QEvent::ShortcutOverride)
93
Q_ASSERT(o == widget);
95
if (QApplication::activePopupWidget()) {
96
if (buttonDown && ee->type() == QEvent::MouseButtonRelease)
101
QMouseEvent *e = (QMouseEvent*)ee;
103
case QEvent::MouseButtonPress: {
104
if (w->isMaximized())
106
if (!widget->rect().contains(widget->mapFromGlobal(e->globalPos())))
108
if (e->button() == Qt::LeftButton) {
110
bool me = movingEnabled;
111
movingEnabled = (me && o == widget);
115
moveOffset = widget->mapFromGlobal(e->globalPos());
116
invertedMoveOffset = widget->rect().bottomRight() - moveOffset;
119
case QEvent::MouseButtonRelease:
120
if (w->isMaximized())
122
if (e->button() == Qt::LeftButton) {
123
moveResizeMode = false;
125
widget->releaseMouse();
126
widget->releaseKeyboard();
129
case QEvent::MouseMove: {
130
if (w->isMaximized())
132
bool me = movingEnabled;
133
movingEnabled = (me && o == widget && buttonDown);
139
case QEvent::KeyPress:
140
keyPressEvent((QKeyEvent*)e);
142
case QEvent::ShortcutOverride:
144
((QKeyEvent*)ee)->accept();
154
void QWidgetResizeHandler::mouseMoveEvent(QMouseEvent *e)
156
QPoint pos = widget->mapFromGlobal(e->globalPos());
157
if (!moveResizeMode && !buttonDown) {
158
if (pos.y() <= range && pos.x() <= range)
160
else if (pos.y() >= widget->height()-range && pos.x() >= widget->width()-range)
162
else if (pos.y() >= widget->height()-range && pos.x() <= range)
164
else if (pos.y() <= range && pos.x() >= widget->width()-range)
166
else if (pos.y() <= range)
168
else if (pos.y() >= widget->height()-range)
170
else if (pos.x() <= range)
172
else if ( pos.x() >= widget->width()-range)
177
if (widget->isMinimized() || !isActive(Resize))
180
setMouseCursor(mode);
185
if (mode == Center && !movingEnabled)
188
if (widget->testAttribute(Qt::WA_WState_ConfigPending))
192
QPoint globalPos = (!widget->isWindow() && widget->parentWidget()) ?
193
widget->parentWidget()->mapFromGlobal(e->globalPos()) : e->globalPos();
194
if (!widget->isWindow() && !widget->parentWidget()->rect().contains(globalPos)) {
195
if (globalPos.x() < 0)
197
if (globalPos.y() < 0)
199
if (sizeprotect && globalPos.x() > widget->parentWidget()->width())
200
globalPos.rx() = widget->parentWidget()->width();
201
if (sizeprotect && globalPos.y() > widget->parentWidget()->height())
202
globalPos.ry() = widget->parentWidget()->height();
205
QPoint p = globalPos + invertedMoveOffset;
206
QPoint pp = globalPos - moveOffset;
208
int mw = qMax(childWidget->minimumSizeHint().width(),
209
childWidget->minimumWidth());
210
int mh = qMax(childWidget->minimumSizeHint().height(),
211
childWidget->minimumHeight());
212
if (childWidget != widget) {
214
mh += 2 * fw + extrahei;
217
QSize mpsize(widget->geometry().right() - pp.x() + 1,
218
widget->geometry().bottom() - pp.y() + 1);
219
mpsize = mpsize.expandedTo(widget->minimumSize()).expandedTo(QSize(mw, mh));
220
QPoint mp(widget->geometry().right() - mpsize.width() + 1,
221
widget->geometry().bottom() - mpsize.height() + 1);
223
QRect geom = widget->geometry();
227
geom = QRect(mp, widget->geometry().bottomRight()) ;
230
geom = QRect(widget->geometry().topLeft(), p) ;
233
geom = QRect(QPoint(mp.x(), widget->geometry().y()), QPoint(widget->geometry().right(), p.y())) ;
236
geom = QRect(QPoint(widget->geometry().x(), mp.y()), QPoint(p.x(), widget->geometry().bottom())) ;
239
geom = QRect(QPoint(widget->geometry().left(), mp.y()), widget->geometry().bottomRight()) ;
242
geom = QRect(widget->geometry().topLeft(), QPoint(widget->geometry().right(), p.y())) ;
245
geom = QRect(QPoint(mp.x(), widget->geometry().top()), widget->geometry().bottomRight()) ;
248
geom = QRect(widget->geometry().topLeft(), QPoint(p.x(), widget->geometry().bottom())) ;
252
geom.moveTopLeft(pp);
258
QSize maxsize(childWidget->maximumSize());
259
if (childWidget != widget)
260
maxsize += QSize(2 * fw, 2 * fw + extrahei);
262
geom = QRect(geom.topLeft(),
263
geom.size().expandedTo(widget->minimumSize())
264
.expandedTo(QSize(mw, mh))
265
.boundedTo(maxsize));
267
if (geom != widget->geometry() &&
268
(widget->isWindow() || widget->parentWidget()->rect().intersects(geom))) {
269
if (widget->isMinimized())
270
widget->move(geom.topLeft());
272
widget->setGeometry(geom);
275
#if defined(Q_WS_WIN)
278
while(PeekMessageW(&msg, widget->winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE))
281
while(PeekMessageA(&msg, widget->winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE))
286
QApplication::syncX();
289
void QWidgetResizeHandler::setMouseCursor(MousePosition m)
292
QObjectList children = widget->children();
293
for (int i = 0; i < children.size(); ++i) {
294
if (QWidget *w = qobject_cast<QWidget*>(children.at(i)))
295
if (!w->testAttribute(Qt::WA_SetCursor))
296
w->setCursor(Qt::ArrowCursor);
302
widget->setCursor(Qt::SizeFDiagCursor);
306
widget->setCursor(Qt::SizeBDiagCursor);
310
widget->setCursor(Qt::SizeVerCursor);
314
widget->setCursor(Qt::SizeHorCursor);
317
widget->setCursor(Qt::ArrowCursor);
323
void QWidgetResizeHandler::keyPressEvent(QKeyEvent * e)
325
if (!isMove() && !isResize())
327
bool is_control = e->modifiers() & Qt::ControlModifier;
328
int delta = is_control?1:8;
329
QPoint pos = QCursor::pos();
333
if (pos.x() <= QApplication::desktop()->geometry().left()) {
334
if (mode == TopLeft || mode == BottomLeft) {
335
moveOffset.rx() += delta;
336
invertedMoveOffset.rx() += delta;
338
moveOffset.rx() -= delta;
339
invertedMoveOffset.rx() -= delta;
342
if (isResize() && !resizeHorizontalDirectionFixed) {
343
resizeHorizontalDirectionFixed = true;
344
if (mode == BottomRight)
346
else if (mode == TopRight)
349
setMouseCursor(mode);
350
widget->grabMouse(widget->cursor());
358
if (pos.x() >= QApplication::desktop()->geometry().right()) {
359
if (mode == TopRight || mode == BottomRight) {
360
moveOffset.rx() += delta;
361
invertedMoveOffset.rx() += delta;
363
moveOffset.rx() -= delta;
364
invertedMoveOffset.rx() -= delta;
367
if (isResize() && !resizeHorizontalDirectionFixed) {
368
resizeHorizontalDirectionFixed = true;
369
if (mode == BottomLeft)
371
else if (mode == TopLeft)
374
setMouseCursor(mode);
375
widget->grabMouse(widget->cursor());
383
if (pos.y() <= QApplication::desktop()->geometry().top()) {
384
if (mode == TopLeft || mode == TopRight) {
385
moveOffset.ry() += delta;
386
invertedMoveOffset.ry() += delta;
388
moveOffset.ry() -= delta;
389
invertedMoveOffset.ry() -= delta;
392
if (isResize() && !resizeVerticalDirectionFixed) {
393
resizeVerticalDirectionFixed = true;
394
if (mode == BottomLeft)
396
else if (mode == BottomRight)
399
setMouseCursor(mode);
400
widget->grabMouse(widget->cursor());
408
if (pos.y() >= QApplication::desktop()->geometry().bottom()) {
409
if (mode == BottomLeft || mode == BottomRight) {
410
moveOffset.ry() += delta;
411
invertedMoveOffset.ry() += delta;
413
moveOffset.ry() -= delta;
414
invertedMoveOffset.ry() -= delta;
417
if (isResize() && !resizeVerticalDirectionFixed) {
418
resizeVerticalDirectionFixed = true;
421
else if (mode == TopRight)
424
setMouseCursor(mode);
425
widget->grabMouse(widget->cursor());
435
moveResizeMode = false;
436
widget->releaseMouse();
437
widget->releaseKeyboard();
443
QCursor::setPos(pos);
447
void QWidgetResizeHandler::doResize()
449
if (!activeForResize)
452
moveResizeMode = true;
454
moveOffset = widget->mapFromGlobal(QCursor::pos());
455
if (moveOffset.x() < widget->width()/2) {
456
if (moveOffset.y() < widget->height()/2)
461
if (moveOffset.y() < widget->height()/2)
466
invertedMoveOffset = widget->rect().bottomRight() - moveOffset;
468
setMouseCursor(mode);
469
widget->grabMouse(widget->cursor() );
473
widget->grabKeyboard();
474
resizeHorizontalDirectionFixed = false;
475
resizeVerticalDirectionFixed = false;
478
void QWidgetResizeHandler::doMove()
484
moveResizeMode = true;
486
moveOffset = widget->mapFromGlobal(QCursor::pos());
487
invertedMoveOffset = widget->rect().bottomRight() - moveOffset;
489
widget->grabMouse(Qt::SizeAllCursor);
493
widget->grabKeyboard();
496
#endif //QT_NO_RESIZEHANDLER