source: trunk/src/widgets/qwidgetresizehandler.cpp

Last change on this file was 8, checked in by dmik, 20 years ago

Transferred Qt for OS/2 version 3.3.1-rc5 sources from the CVS

  • Property svn:keywords set to Id
File size: 14.5 KB
Line 
1/****************************************************************************
2** $Id: qwidgetresizehandler.cpp 8 2005-11-16 19:36:46Z dmik $
3**
4** Implementation of the QWidgetResizeHandler class
5**
6** Created : 001010
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the workspace module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qwidgetresizehandler_p.h"
39
40#ifndef QT_NO_RESIZEHANDLER
41#include "qframe.h"
42#include "qapplication.h"
43#include "qcursor.h"
44#include "qsizegrip.h"
45#if defined(Q_WS_WIN)
46#include "qt_windows.h"
47#elif defined(Q_WS_PM)
48#include "qt_os2.h"
49#endif
50
51#define RANGE 4
52
53static bool resizeHorizontalDirectionFixed = FALSE;
54static bool resizeVerticalDirectionFixed = FALSE;
55
56QWidgetResizeHandler::QWidgetResizeHandler( QWidget *parent, QWidget *cw, const char *name )
57 : QObject( parent, name ), widget( parent ), childWidget( cw ? cw : parent ),
58 extrahei( 0 ), buttonDown( FALSE ), moveResizeMode( FALSE ), sizeprotect( TRUE ), moving( TRUE )
59{
60 mode = Nowhere;
61 widget->setMouseTracking( TRUE );
62 QFrame *frame = ::qt_cast<QFrame*>(widget);
63 range = frame ? frame->frameWidth() : RANGE;
64 range = QMAX( RANGE, range );
65 activeForMove = activeForResize = TRUE;
66 qApp->installEventFilter( this );
67}
68
69void QWidgetResizeHandler::setActive( Action ac, bool b )
70{
71 if ( ac & Move )
72 activeForMove = b;
73 if ( ac & Resize )
74 activeForResize = b;
75
76 if ( !isActive() )
77 setMouseCursor( Nowhere );
78}
79
80bool QWidgetResizeHandler::isActive( Action ac ) const
81{
82 bool b = FALSE;
83 if ( ac & Move ) b = activeForMove;
84 if ( ac & Resize ) b |= activeForResize;
85
86 return b;
87}
88
89static QWidget *childOf( QWidget *w, QWidget *child )
90{
91 while ( child ) {
92 if ( child == w )
93 return child;
94 if ( child->isTopLevel() )
95 break;
96 child = child->parentWidget();
97 }
98 return 0;
99}
100
101bool QWidgetResizeHandler::eventFilter( QObject *o, QEvent *ee )
102{
103 if ( !isActive() || !o->isWidgetType() || !ee->spontaneous())
104 return FALSE;
105
106 if ( ee->type() != QEvent::MouseButtonPress &&
107 ee->type() != QEvent::MouseButtonRelease &&
108 ee->type() != QEvent::MouseMove &&
109 ee->type() != QEvent::KeyPress &&
110 ee->type() != QEvent::AccelOverride )
111 return FALSE;
112
113 QWidget *w = childOf( widget, (QWidget*)o );
114 if ( !w
115#ifndef QT_NO_SIZEGRIP
116 || ::qt_cast<QSizeGrip*>(o)
117#endif
118 || qApp->activePopupWidget() ) {
119 if ( buttonDown && ee->type() == QEvent::MouseButtonRelease )
120 buttonDown = FALSE;
121 return FALSE;
122 }
123
124 QMouseEvent *e = (QMouseEvent*)ee;
125 switch ( e->type() ) {
126 case QEvent::MouseButtonPress: {
127 if ( w->isMaximized() )
128 break;
129 if ( !widget->rect().contains( widget->mapFromGlobal( e->globalPos() ) ) )
130 return FALSE;
131 if ( e->button() == LeftButton ) {
132 emit activate();
133 bool me = isMovingEnabled();
134 setMovingEnabled( me && o == widget );
135 mouseMoveEvent( e );
136 setMovingEnabled( me );
137 buttonDown = TRUE;
138 moveOffset = widget->mapFromGlobal( e->globalPos() );
139 invertedMoveOffset = widget->rect().bottomRight() - moveOffset;
140 }
141 } break;
142 case QEvent::MouseButtonRelease:
143 if ( w->isMaximized() )
144 break;
145 if ( e->button() == LeftButton ) {
146 moveResizeMode = FALSE;
147 buttonDown = FALSE;
148 widget->releaseMouse();
149 widget->releaseKeyboard();
150 }
151 break;
152 case QEvent::MouseMove: {
153 if ( w->isMaximized() )
154 break;
155 bool me = isMovingEnabled();
156 setMovingEnabled( me && o == widget );
157 mouseMoveEvent( e );
158 setMovingEnabled( me );
159 if ( buttonDown && mode != Center )
160 return TRUE;
161 } break;
162 case QEvent::KeyPress:
163 keyPressEvent( (QKeyEvent*)e );
164 break;
165 case QEvent::AccelOverride:
166 if ( buttonDown ) {
167 ((QKeyEvent*)ee)->accept();
168 return TRUE;
169 }
170 break;
171 default:
172 break;
173 }
174 return FALSE;
175}
176
177void QWidgetResizeHandler::mouseMoveEvent( QMouseEvent *e )
178{
179 QPoint pos = widget->mapFromGlobal( e->globalPos() );
180 if ( !moveResizeMode && ( !buttonDown || ( e->state() & LeftButton ) == 0 ) ) {
181 if ( pos.y() <= range && pos.x() <= range)
182 mode = TopLeft;
183 else if ( pos.y() >= widget->height()-range && pos.x() >= widget->width()-range)
184 mode = BottomRight;
185 else if ( pos.y() >= widget->height()-range && pos.x() <= range)
186 mode = BottomLeft;
187 else if ( pos.y() <= range && pos.x() >= widget->width()-range)
188 mode = TopRight;
189 else if ( pos.y() <= range )
190 mode = Top;
191 else if ( pos.y() >= widget->height()-range )
192 mode = Bottom;
193 else if ( pos.x() <= range )
194 mode = Left;
195 else if ( pos.x() >= widget->width()-range )
196 mode = Right;
197 else
198 mode = Center;
199
200 if ( widget->isMinimized() || !isActive(Resize) )
201 mode = Center;
202#ifndef QT_NO_CURSOR
203 setMouseCursor( mode );
204#endif
205 return;
206 }
207
208 if ( buttonDown && !isMovingEnabled() && mode == Center && !moveResizeMode )
209 return;
210
211 if ( widget->testWState( WState_ConfigPending ) )
212 return;
213
214 QPoint globalPos = widget->parentWidget( TRUE ) ?
215 widget->parentWidget( TRUE )->mapFromGlobal( e->globalPos() ) : e->globalPos();
216 if ( widget->parentWidget( TRUE ) && !widget->parentWidget( TRUE )->rect().contains( globalPos ) ) {
217 if ( globalPos.x() < 0 )
218 globalPos.rx() = 0;
219 if ( globalPos.y() < 0 )
220 globalPos.ry() = 0;
221 if ( sizeprotect && globalPos.x() > widget->parentWidget()->width() )
222 globalPos.rx() = widget->parentWidget()->width();
223 if ( sizeprotect && globalPos.y() > widget->parentWidget()->height() )
224 globalPos.ry() = widget->parentWidget()->height();
225 }
226
227 QPoint p = globalPos + invertedMoveOffset;
228 QPoint pp = globalPos - moveOffset;
229
230 int fw = 0;
231 int mw = QMAX( childWidget->minimumSizeHint().width(),
232 childWidget->minimumWidth() );
233 int mh = QMAX( childWidget->minimumSizeHint().height(),
234 childWidget->minimumHeight() );
235 if ( childWidget != widget ) {
236 QFrame *frame = ::qt_cast<QFrame*>(widget);
237 if ( frame )
238 fw = frame->frameWidth();
239 mw += 2 * fw;
240 mh += 2 * fw + extrahei;
241 }
242
243 QSize mpsize( widget->geometry().right() - pp.x() + 1,
244 widget->geometry().bottom() - pp.y() + 1 );
245 mpsize = mpsize.expandedTo( widget->minimumSize() ).expandedTo( QSize(mw, mh) );
246 QPoint mp( widget->geometry().right() - mpsize.width() + 1,
247 widget->geometry().bottom() - mpsize.height() + 1 );
248
249 QRect geom = widget->geometry();
250
251 switch ( mode ) {
252 case TopLeft:
253 geom = QRect( mp, widget->geometry().bottomRight() ) ;
254 break;
255 case BottomRight:
256 geom = QRect( widget->geometry().topLeft(), p ) ;
257 break;
258 case BottomLeft:
259 geom = QRect( QPoint(mp.x(), widget->geometry().y() ), QPoint( widget->geometry().right(), p.y()) ) ;
260 break;
261 case TopRight:
262 geom = QRect( QPoint( widget->geometry().x(), mp.y() ), QPoint( p.x(), widget->geometry().bottom()) ) ;
263 break;
264 case Top:
265 geom = QRect( QPoint( widget->geometry().left(), mp.y() ), widget->geometry().bottomRight() ) ;
266 break;
267 case Bottom:
268 geom = QRect( widget->geometry().topLeft(), QPoint( widget->geometry().right(), p.y() ) ) ;
269 break;
270 case Left:
271 geom = QRect( QPoint( mp.x(), widget->geometry().top() ), widget->geometry().bottomRight() ) ;
272 break;
273 case Right:
274 geom = QRect( widget->geometry().topLeft(), QPoint( p.x(), widget->geometry().bottom() ) ) ;
275 break;
276 case Center:
277 if ( isMovingEnabled() || moveResizeMode )
278 geom.moveTopLeft( pp );
279 break;
280 default:
281 break;
282 }
283
284 QSize maxsize( childWidget->maximumSize() );
285 if ( childWidget != widget )
286 maxsize += QSize( 2 * fw, 2 * fw + extrahei );
287
288 geom = QRect( geom.topLeft(),
289 geom.size().expandedTo( widget->minimumSize() )
290 .expandedTo( QSize(mw, mh) )
291 .boundedTo( maxsize ) );
292
293 if ( geom != widget->geometry() &&
294 ( widget->isTopLevel() || widget->parentWidget()->rect().intersects( geom ) ) ) {
295 if ( widget->isMinimized() )
296 widget->move( geom.topLeft() );
297 else
298 widget->setGeometry( geom );
299 }
300
301#if defined(Q_WS_WIN)
302 MSG msg;
303 QT_WA( {
304 while(PeekMessageW( &msg, widget->winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE ))
305 ;
306 } , {
307 while(PeekMessageA( &msg, widget->winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE ))
308 ;
309 } );
310#elif defined(Q_WS_PM)
311 QMSG qmsg;
312 while( WinPeekMsg( 0, &qmsg, widget->winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE ) )
313 ;
314#endif
315
316 QApplication::syncX();
317}
318
319void QWidgetResizeHandler::setMouseCursor( MousePosition m )
320{
321#ifndef QT_NO_CURSOR
322 switch ( m ) {
323 case TopLeft:
324 case BottomRight:
325 widget->setCursor( sizeFDiagCursor );
326 break;
327 case BottomLeft:
328 case TopRight:
329 widget->setCursor( sizeBDiagCursor );
330 break;
331 case Top:
332 case Bottom:
333 widget->setCursor( sizeVerCursor );
334 break;
335 case Left:
336 case Right:
337 widget->setCursor( sizeHorCursor );
338 break;
339 default:
340 widget->setCursor( arrowCursor );
341 break;
342 }
343#endif
344}
345
346void QWidgetResizeHandler::keyPressEvent( QKeyEvent * e )
347{
348 if ( !isMove() && !isResize() )
349 return;
350 bool is_control = e->state() & ControlButton;
351 int delta = is_control?1:8;
352 QPoint pos = QCursor::pos();
353 switch ( e->key() ) {
354 case Key_Left:
355 pos.rx() -= delta;
356 if ( pos.x() <= QApplication::desktop()->geometry().left() ) {
357 if ( mode == TopLeft || mode == BottomLeft ) {
358 moveOffset.rx() += delta;
359 invertedMoveOffset.rx() += delta;
360 } else {
361 moveOffset.rx() -= delta;
362 invertedMoveOffset.rx() -= delta;
363 }
364 }
365 if ( isResize() && !resizeHorizontalDirectionFixed ) {
366 resizeHorizontalDirectionFixed = TRUE;
367 if ( mode == BottomRight )
368 mode = BottomLeft;
369 else if ( mode == TopRight )
370 mode = TopLeft;
371#ifndef QT_NO_CURSOR
372 setMouseCursor( mode );
373 widget->grabMouse( widget->cursor() );
374#else
375 widget->grabMouse();
376#endif
377 }
378 break;
379 case Key_Right:
380 pos.rx() += delta;
381 if ( pos.x() >= QApplication::desktop()->geometry().right() ) {
382 if ( mode == TopRight || mode == BottomRight ) {
383 moveOffset.rx() += delta;
384 invertedMoveOffset.rx() += delta;
385 } else {
386 moveOffset.rx() -= delta;
387 invertedMoveOffset.rx() -= delta;
388 }
389 }
390 if ( isResize() && !resizeHorizontalDirectionFixed ) {
391 resizeHorizontalDirectionFixed = TRUE;
392 if ( mode == BottomLeft )
393 mode = BottomRight;
394 else if ( mode == TopLeft )
395 mode = TopRight;
396#ifndef QT_NO_CURSOR
397 setMouseCursor( mode );
398 widget->grabMouse( widget->cursor() );
399#else
400 widget->grabMouse();
401#endif
402 }
403 break;
404 case Key_Up:
405 pos.ry() -= delta;
406 if ( pos.y() <= QApplication::desktop()->geometry().top() ) {
407 if ( mode == TopLeft || mode == TopRight ) {
408 moveOffset.ry() += delta;
409 invertedMoveOffset.ry() += delta;
410 } else {
411 moveOffset.ry() -= delta;
412 invertedMoveOffset.ry() -= delta;
413 }
414 }
415 if ( isResize() && !resizeVerticalDirectionFixed ) {
416 resizeVerticalDirectionFixed = TRUE;
417 if ( mode == BottomLeft )
418 mode = TopLeft;
419 else if ( mode == BottomRight )
420 mode = TopRight;
421#ifndef QT_NO_CURSOR
422 setMouseCursor( mode );
423 widget->grabMouse( widget->cursor() );
424#else
425 widget->grabMouse();
426#endif
427 }
428 break;
429 case Key_Down:
430 pos.ry() += delta;
431 if ( pos.y() >= QApplication::desktop()->geometry().bottom() ) {
432 if ( mode == BottomLeft || mode == BottomRight ) {
433 moveOffset.ry() += delta;
434 invertedMoveOffset.ry() += delta;
435 } else {
436 moveOffset.ry() -= delta;
437 invertedMoveOffset.ry() -= delta;
438 }
439 }
440 if ( isResize() && !resizeVerticalDirectionFixed ) {
441 resizeVerticalDirectionFixed = TRUE;
442 if ( mode == TopLeft )
443 mode = BottomLeft;
444 else if ( mode == TopRight )
445 mode = BottomRight;
446#ifndef QT_NO_CURSOR
447 setMouseCursor( mode );
448 widget->grabMouse( widget->cursor() );
449#else
450 widget->grabMouse();
451#endif
452 }
453 break;
454 case Key_Space:
455 case Key_Return:
456 case Key_Enter:
457 case Key_Escape:
458 moveResizeMode = FALSE;
459 widget->releaseMouse();
460 widget->releaseKeyboard();
461 buttonDown = FALSE;
462 break;
463 default:
464 return;
465 }
466 QCursor::setPos( pos );
467}
468
469
470void QWidgetResizeHandler::doResize()
471{
472 if ( !activeForResize )
473 return;
474
475 moveResizeMode = TRUE;
476 buttonDown = TRUE;
477 moveOffset = widget->mapFromGlobal( QCursor::pos() );
478 if ( moveOffset.x() < widget->width()/2) {
479 if ( moveOffset.y() < widget->height()/2)
480 mode = TopLeft;
481 else
482 mode = BottomLeft;
483 } else {
484 if ( moveOffset.y() < widget->height()/2)
485 mode = TopRight;
486 else
487 mode = BottomRight;
488 }
489 invertedMoveOffset = widget->rect().bottomRight() - moveOffset;
490#ifndef QT_NO_CURSOR
491 setMouseCursor( mode );
492 widget->grabMouse( widget->cursor() );
493#else
494 widget->grabMouse();
495#endif
496 widget->grabKeyboard();
497 resizeHorizontalDirectionFixed = FALSE;
498 resizeVerticalDirectionFixed = FALSE;
499}
500
501void QWidgetResizeHandler::doMove()
502{
503 if ( !activeForMove )
504 return;
505
506 mode = Center;
507 moveResizeMode = TRUE;
508 buttonDown = TRUE;
509 moveOffset = widget->mapFromGlobal( QCursor::pos() );
510 invertedMoveOffset = widget->rect().bottomRight() - moveOffset;
511#ifndef QT_NO_CURSOR
512 widget->grabMouse( SizeAllCursor );
513#else
514 widget->grabMouse();
515#endif
516 widget->grabKeyboard();
517}
518
519#endif //QT_NO_RESIZEHANDLER
Note: See TracBrowser for help on using the repository browser.