~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/gui/widgets/qwidgetresizehandler.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the widgets module of the Qt Toolkit.
 
6
**
 
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.
 
10
**
 
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.
 
15
**
 
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.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
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.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "qwidgetresizehandler_p.h"
 
30
 
 
31
#ifndef QT_NO_RESIZEHANDLER
 
32
#include "qframe.h"
 
33
#include "qapplication.h"
 
34
#include "qdesktopwidget.h"
 
35
#include "qcursor.h"
 
36
#include "qsizegrip.h"
 
37
#include "qevent.h"
 
38
#if defined(Q_WS_WIN)
 
39
#include "qt_windows.h"
 
40
#endif
 
41
#include "qdebug.h"
 
42
 
 
43
#define RANGE 4
 
44
 
 
45
static bool resizeHorizontalDirectionFixed = false;
 
46
static bool resizeVerticalDirectionFixed = false;
 
47
 
 
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)
 
51
{
 
52
    mode = Nowhere;
 
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);
 
59
}
 
60
 
 
61
void QWidgetResizeHandler::setActive(Action ac, bool b)
 
62
{
 
63
    if (ac & Move)
 
64
        activeForMove = b;
 
65
    if (ac & Resize)
 
66
        activeForResize = b;
 
67
 
 
68
    if (!isActive())
 
69
        setMouseCursor(Nowhere);
 
70
}
 
71
 
 
72
bool QWidgetResizeHandler::isActive(Action ac) const
 
73
{
 
74
    bool b = false;
 
75
    if (ac & Move) b = activeForMove;
 
76
    if (ac & Resize) b |= activeForResize;
 
77
 
 
78
    return b;
 
79
}
 
80
 
 
81
bool QWidgetResizeHandler::eventFilter(QObject *o, QEvent *ee)
 
82
{
 
83
    if (!isActive() || !ee->spontaneous())
 
84
        return false;
 
85
 
 
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)
 
91
        return false;
 
92
 
 
93
    Q_ASSERT(o == widget);
 
94
    QWidget *w = widget;
 
95
    if (QApplication::activePopupWidget()) {
 
96
        if (buttonDown && ee->type() == QEvent::MouseButtonRelease)
 
97
            buttonDown = false;
 
98
        return false;
 
99
    }
 
100
 
 
101
    QMouseEvent *e = (QMouseEvent*)ee;
 
102
    switch (e->type()) {
 
103
    case QEvent::MouseButtonPress: {
 
104
        if (w->isMaximized())
 
105
            break;
 
106
        if (!widget->rect().contains(widget->mapFromGlobal(e->globalPos())))
 
107
            return false;
 
108
        if (e->button() == Qt::LeftButton) {
 
109
            emit activate();
 
110
            bool me = movingEnabled;
 
111
            movingEnabled = (me && o == widget);
 
112
            mouseMoveEvent(e);
 
113
            movingEnabled = me;
 
114
            buttonDown = true;
 
115
            moveOffset = widget->mapFromGlobal(e->globalPos());
 
116
            invertedMoveOffset = widget->rect().bottomRight() - moveOffset;
 
117
        }
 
118
    } break;
 
119
    case QEvent::MouseButtonRelease:
 
120
        if (w->isMaximized())
 
121
            break;
 
122
        if (e->button() == Qt::LeftButton) {
 
123
            moveResizeMode = false;
 
124
            buttonDown = false;
 
125
            widget->releaseMouse();
 
126
            widget->releaseKeyboard();
 
127
        }
 
128
        break;
 
129
    case QEvent::MouseMove: {
 
130
        if (w->isMaximized())
 
131
            break;
 
132
        bool me = movingEnabled;
 
133
        movingEnabled = (me && o == widget && buttonDown);
 
134
        mouseMoveEvent(e);
 
135
        movingEnabled = me;
 
136
        if (mode != Center)
 
137
            return true;
 
138
    } break;
 
139
    case QEvent::KeyPress:
 
140
        keyPressEvent((QKeyEvent*)e);
 
141
        break;
 
142
    case QEvent::ShortcutOverride:
 
143
        if (buttonDown) {
 
144
            ((QKeyEvent*)ee)->accept();
 
145
            return true;
 
146
        }
 
147
        break;
 
148
    default:
 
149
        break;
 
150
    }
 
151
    return false;
 
152
}
 
153
 
 
154
void QWidgetResizeHandler::mouseMoveEvent(QMouseEvent *e)
 
155
{
 
156
    QPoint pos = widget->mapFromGlobal(e->globalPos());
 
157
    if (!moveResizeMode && !buttonDown) {
 
158
        if (pos.y() <= range && pos.x() <= range)
 
159
            mode = TopLeft;
 
160
        else if (pos.y() >= widget->height()-range && pos.x() >= widget->width()-range)
 
161
            mode = BottomRight;
 
162
        else if (pos.y() >= widget->height()-range && pos.x() <= range)
 
163
            mode = BottomLeft;
 
164
        else if (pos.y() <= range && pos.x() >= widget->width()-range)
 
165
            mode = TopRight;
 
166
        else if (pos.y() <= range)
 
167
            mode = Top;
 
168
        else if (pos.y() >= widget->height()-range)
 
169
            mode = Bottom;
 
170
        else if (pos.x() <= range)
 
171
            mode = Left;
 
172
        else if ( pos.x() >= widget->width()-range)
 
173
            mode = Right;
 
174
        else
 
175
            mode = Center;
 
176
 
 
177
        if (widget->isMinimized() || !isActive(Resize))
 
178
            mode = Center;
 
179
#ifndef QT_NO_CURSOR
 
180
        setMouseCursor(mode);
 
181
#endif
 
182
        return;
 
183
    }
 
184
 
 
185
    if (mode == Center && !movingEnabled)
 
186
        return;
 
187
 
 
188
    if (widget->testAttribute(Qt::WA_WState_ConfigPending))
 
189
        return;
 
190
 
 
191
 
 
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)
 
196
            globalPos.rx() = 0;
 
197
        if (globalPos.y() < 0)
 
198
            globalPos.ry() = 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();
 
203
    }
 
204
 
 
205
    QPoint p = globalPos + invertedMoveOffset;
 
206
    QPoint pp = globalPos - moveOffset;
 
207
 
 
208
    int mw = qMax(childWidget->minimumSizeHint().width(),
 
209
                   childWidget->minimumWidth());
 
210
    int mh = qMax(childWidget->minimumSizeHint().height(),
 
211
                   childWidget->minimumHeight());
 
212
    if (childWidget != widget) {
 
213
        mw += 2 * fw;
 
214
        mh += 2 * fw + extrahei;
 
215
    }
 
216
 
 
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);
 
222
 
 
223
    QRect geom = widget->geometry();
 
224
 
 
225
    switch (mode) {
 
226
    case TopLeft:
 
227
        geom = QRect(mp, widget->geometry().bottomRight()) ;
 
228
        break;
 
229
    case BottomRight:
 
230
        geom = QRect(widget->geometry().topLeft(), p) ;
 
231
        break;
 
232
    case BottomLeft:
 
233
        geom = QRect(QPoint(mp.x(), widget->geometry().y()), QPoint(widget->geometry().right(), p.y())) ;
 
234
        break;
 
235
    case TopRight:
 
236
        geom = QRect(QPoint(widget->geometry().x(), mp.y()), QPoint(p.x(), widget->geometry().bottom())) ;
 
237
        break;
 
238
    case Top:
 
239
        geom = QRect(QPoint(widget->geometry().left(), mp.y()), widget->geometry().bottomRight()) ;
 
240
        break;
 
241
    case Bottom:
 
242
        geom = QRect(widget->geometry().topLeft(), QPoint(widget->geometry().right(), p.y())) ;
 
243
        break;
 
244
    case Left:
 
245
        geom = QRect(QPoint(mp.x(), widget->geometry().top()), widget->geometry().bottomRight()) ;
 
246
        break;
 
247
    case Right:
 
248
        geom = QRect(widget->geometry().topLeft(), QPoint(p.x(), widget->geometry().bottom())) ;
 
249
        break;
 
250
    case Center:
 
251
        if (moveResizeMode)
 
252
            geom.moveTopLeft(pp);
 
253
        break;
 
254
    default:
 
255
        break;
 
256
    }
 
257
 
 
258
    QSize maxsize(childWidget->maximumSize());
 
259
    if (childWidget != widget)
 
260
        maxsize += QSize(2 * fw, 2 * fw + extrahei);
 
261
 
 
262
    geom = QRect(geom.topLeft(),
 
263
                  geom.size().expandedTo(widget->minimumSize())
 
264
                             .expandedTo(QSize(mw, mh))
 
265
                             .boundedTo(maxsize));
 
266
 
 
267
    if (geom != widget->geometry() &&
 
268
        (widget->isWindow() || widget->parentWidget()->rect().intersects(geom))) {
 
269
        if (widget->isMinimized())
 
270
            widget->move(geom.topLeft());
 
271
        else
 
272
            widget->setGeometry(geom);
 
273
    }
 
274
 
 
275
#if defined(Q_WS_WIN)
 
276
    MSG msg;
 
277
    QT_WA({
 
278
        while(PeekMessageW(&msg, widget->winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE))
 
279
            ;
 
280
    } , {
 
281
        while(PeekMessageA(&msg, widget->winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE))
 
282
            ;
 
283
    });
 
284
#endif
 
285
 
 
286
    QApplication::syncX();
 
287
}
 
288
 
 
289
void QWidgetResizeHandler::setMouseCursor(MousePosition m)
 
290
{
 
291
#ifndef QT_NO_CURSOR
 
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);
 
297
    }
 
298
 
 
299
    switch (m) {
 
300
    case TopLeft:
 
301
    case BottomRight:
 
302
        widget->setCursor(Qt::SizeFDiagCursor);
 
303
        break;
 
304
    case BottomLeft:
 
305
    case TopRight:
 
306
        widget->setCursor(Qt::SizeBDiagCursor);
 
307
        break;
 
308
    case Top:
 
309
    case Bottom:
 
310
        widget->setCursor(Qt::SizeVerCursor);
 
311
        break;
 
312
    case Left:
 
313
    case Right:
 
314
        widget->setCursor(Qt::SizeHorCursor);
 
315
        break;
 
316
    default:
 
317
        widget->setCursor(Qt::ArrowCursor);
 
318
        break;
 
319
    }
 
320
#endif
 
321
}
 
322
 
 
323
void QWidgetResizeHandler::keyPressEvent(QKeyEvent * e)
 
324
{
 
325
    if (!isMove() && !isResize())
 
326
        return;
 
327
    bool is_control = e->modifiers() & Qt::ControlModifier;
 
328
    int delta = is_control?1:8;
 
329
    QPoint pos = QCursor::pos();
 
330
    switch (e->key()) {
 
331
    case Qt::Key_Left:
 
332
        pos.rx() -= delta;
 
333
        if (pos.x() <= QApplication::desktop()->geometry().left()) {
 
334
            if (mode == TopLeft || mode == BottomLeft) {
 
335
                moveOffset.rx() += delta;
 
336
                invertedMoveOffset.rx() += delta;
 
337
            } else {
 
338
                moveOffset.rx() -= delta;
 
339
                invertedMoveOffset.rx() -= delta;
 
340
            }
 
341
        }
 
342
        if (isResize() && !resizeHorizontalDirectionFixed) {
 
343
            resizeHorizontalDirectionFixed = true;
 
344
            if (mode == BottomRight)
 
345
                mode = BottomLeft;
 
346
            else if (mode == TopRight)
 
347
                mode = TopLeft;
 
348
#ifndef QT_NO_CURSOR
 
349
            setMouseCursor(mode);
 
350
            widget->grabMouse(widget->cursor());
 
351
#else
 
352
            widget->grabMouse();
 
353
#endif
 
354
        }
 
355
        break;
 
356
    case Qt::Key_Right:
 
357
        pos.rx() += delta;
 
358
        if (pos.x() >= QApplication::desktop()->geometry().right()) {
 
359
            if (mode == TopRight || mode == BottomRight) {
 
360
                moveOffset.rx() += delta;
 
361
                invertedMoveOffset.rx() += delta;
 
362
            } else {
 
363
                moveOffset.rx() -= delta;
 
364
                invertedMoveOffset.rx() -= delta;
 
365
            }
 
366
        }
 
367
        if (isResize() && !resizeHorizontalDirectionFixed) {
 
368
            resizeHorizontalDirectionFixed = true;
 
369
            if (mode == BottomLeft)
 
370
                mode = BottomRight;
 
371
            else if (mode == TopLeft)
 
372
                mode = TopRight;
 
373
#ifndef QT_NO_CURSOR
 
374
            setMouseCursor(mode);
 
375
            widget->grabMouse(widget->cursor());
 
376
#else
 
377
            widget->grabMouse();
 
378
#endif
 
379
        }
 
380
        break;
 
381
    case Qt::Key_Up:
 
382
        pos.ry() -= delta;
 
383
        if (pos.y() <= QApplication::desktop()->geometry().top()) {
 
384
            if (mode == TopLeft || mode == TopRight) {
 
385
                moveOffset.ry() += delta;
 
386
                invertedMoveOffset.ry() += delta;
 
387
            } else {
 
388
                moveOffset.ry() -= delta;
 
389
                invertedMoveOffset.ry() -= delta;
 
390
            }
 
391
        }
 
392
        if (isResize() && !resizeVerticalDirectionFixed) {
 
393
            resizeVerticalDirectionFixed = true;
 
394
            if (mode == BottomLeft)
 
395
                mode = TopLeft;
 
396
            else if (mode == BottomRight)
 
397
                mode = TopRight;
 
398
#ifndef QT_NO_CURSOR
 
399
            setMouseCursor(mode);
 
400
            widget->grabMouse(widget->cursor());
 
401
#else
 
402
            widget->grabMouse();
 
403
#endif
 
404
        }
 
405
        break;
 
406
    case Qt::Key_Down:
 
407
        pos.ry() += delta;
 
408
        if (pos.y() >= QApplication::desktop()->geometry().bottom()) {
 
409
            if (mode == BottomLeft || mode == BottomRight) {
 
410
                moveOffset.ry() += delta;
 
411
                invertedMoveOffset.ry() += delta;
 
412
            } else {
 
413
                moveOffset.ry() -= delta;
 
414
                invertedMoveOffset.ry() -= delta;
 
415
            }
 
416
        }
 
417
        if (isResize() && !resizeVerticalDirectionFixed) {
 
418
            resizeVerticalDirectionFixed = true;
 
419
            if (mode == TopLeft)
 
420
                mode = BottomLeft;
 
421
            else if (mode == TopRight)
 
422
                mode = BottomRight;
 
423
#ifndef QT_NO_CURSOR
 
424
            setMouseCursor(mode);
 
425
            widget->grabMouse(widget->cursor());
 
426
#else
 
427
            widget->grabMouse();
 
428
#endif
 
429
        }
 
430
        break;
 
431
    case Qt::Key_Space:
 
432
    case Qt::Key_Return:
 
433
    case Qt::Key_Enter:
 
434
    case Qt::Key_Escape:
 
435
        moveResizeMode = false;
 
436
        widget->releaseMouse();
 
437
        widget->releaseKeyboard();
 
438
        buttonDown = false;
 
439
        break;
 
440
    default:
 
441
        return;
 
442
    }
 
443
    QCursor::setPos(pos);
 
444
}
 
445
 
 
446
 
 
447
void QWidgetResizeHandler::doResize()
 
448
{
 
449
    if (!activeForResize)
 
450
        return;
 
451
 
 
452
    moveResizeMode = true;
 
453
    buttonDown = true;
 
454
    moveOffset = widget->mapFromGlobal(QCursor::pos());
 
455
    if (moveOffset.x() < widget->width()/2) {
 
456
        if (moveOffset.y() < widget->height()/2)
 
457
            mode = TopLeft;
 
458
        else
 
459
            mode = BottomLeft;
 
460
    } else {
 
461
        if (moveOffset.y() < widget->height()/2)
 
462
            mode = TopRight;
 
463
        else
 
464
            mode = BottomRight;
 
465
    }
 
466
    invertedMoveOffset = widget->rect().bottomRight() - moveOffset;
 
467
#ifndef QT_NO_CURSOR
 
468
    setMouseCursor(mode);
 
469
    widget->grabMouse(widget->cursor() );
 
470
#else
 
471
    widget->grabMouse();
 
472
#endif
 
473
    widget->grabKeyboard();
 
474
    resizeHorizontalDirectionFixed = false;
 
475
    resizeVerticalDirectionFixed = false;
 
476
}
 
477
 
 
478
void QWidgetResizeHandler::doMove()
 
479
{
 
480
    if (!activeForMove)
 
481
        return;
 
482
 
 
483
    mode = Center;
 
484
    moveResizeMode = true;
 
485
    buttonDown = true;
 
486
    moveOffset = widget->mapFromGlobal(QCursor::pos());
 
487
    invertedMoveOffset = widget->rect().bottomRight() - moveOffset;
 
488
#ifndef QT_NO_CURSOR
 
489
    widget->grabMouse(Qt::SizeAllCursor);
 
490
#else
 
491
    widget->grabMouse();
 
492
#endif
 
493
    widget->grabKeyboard();
 
494
}
 
495
 
 
496
#endif //QT_NO_RESIZEHANDLER