source: trunk/src/gui/widgets/qsizegrip.cpp@ 986

Last change on this file since 986 was 846, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 17.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qsizegrip.h"
43
44#ifndef QT_NO_SIZEGRIP
45
46#include "qapplication.h"
47#include "qevent.h"
48#include "qpainter.h"
49#include "qstyle.h"
50#include "qstyleoption.h"
51#include "qlayout.h"
52#include "qdebug.h"
53#include <QDesktopWidget>
54
55#if defined(Q_WS_X11)
56#include <private/qt_x11_p.h>
57#elif defined (Q_WS_WIN)
58#include "qt_windows.h"
59#endif
60#ifdef Q_WS_MAC
61#include <private/qt_mac_p.h>
62#endif
63
64#include <private/qwidget_p.h>
65#include <QtGui/qabstractscrollarea.h>
66
67#define SZ_SIZEBOTTOMRIGHT 0xf008
68#define SZ_SIZEBOTTOMLEFT 0xf007
69#define SZ_SIZETOPLEFT 0xf004
70#define SZ_SIZETOPRIGHT 0xf005
71
72QT_BEGIN_NAMESPACE
73
74static QWidget *qt_sizegrip_topLevelWidget(QWidget* w)
75{
76 while (w && !w->isWindow() && w->windowType() != Qt::SubWindow)
77 w = w->parentWidget();
78 return w;
79}
80
81static inline bool hasHeightForWidth(QWidget *widget)
82{
83 if (!widget)
84 return false;
85 if (QLayout *layout = widget->layout())
86 return layout->hasHeightForWidth();
87 return widget->sizePolicy().hasHeightForWidth();
88}
89
90class QSizeGripPrivate : public QWidgetPrivate
91{
92 Q_DECLARE_PUBLIC(QSizeGrip)
93public:
94 void init();
95 QPoint p;
96 QRect r;
97 int d;
98 int dxMax;
99 int dyMax;
100 Qt::Corner m_corner;
101 bool gotMousePress;
102 QWidget *tlw;
103#ifdef Q_WS_MAC
104 void updateMacSizer(bool hide) const;
105#endif
106 Qt::Corner corner() const;
107 inline bool atBottom() const
108 {
109 return m_corner == Qt::BottomRightCorner || m_corner == Qt::BottomLeftCorner;
110 }
111
112 inline bool atLeft() const
113 {
114 return m_corner == Qt::BottomLeftCorner || m_corner == Qt::TopLeftCorner;
115 }
116
117 void updateTopLevelWidget()
118 {
119 Q_Q(QSizeGrip);
120 QWidget *w = qt_sizegrip_topLevelWidget(q);
121 if (tlw == w)
122 return;
123 if (tlw)
124 tlw->removeEventFilter(q);
125 tlw = w;
126 if (tlw)
127 tlw->installEventFilter(q);
128 }
129
130 // This slot is invoked by QLayout when the size grip is added to
131 // a layout or reparented after the tlw is shown. This re-implementation is basically
132 // the same as QWidgetPrivate::_q_showIfNotHidden except that it checks
133 // for Qt::WindowFullScreen and Qt::WindowMaximized as well.
134 void _q_showIfNotHidden()
135 {
136 Q_Q(QSizeGrip);
137 bool showSizeGrip = !(q->isHidden() && q->testAttribute(Qt::WA_WState_ExplicitShowHide));
138 updateTopLevelWidget();
139 if (tlw && showSizeGrip) {
140 Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
141#ifndef Q_WS_MAC
142 sizeGripNotVisibleState |= Qt::WindowMaximized;
143#endif
144 // Don't show the size grip if the tlw is maximized or in full screen mode.
145 showSizeGrip = !(tlw->windowState() & sizeGripNotVisibleState);
146 }
147 if (showSizeGrip)
148 q->setVisible(true);
149 }
150};
151
152#ifdef Q_WS_MAC
153void QSizeGripPrivate::updateMacSizer(bool hide) const
154{
155 Q_Q(const QSizeGrip);
156 if (QApplication::closingDown() || !parent)
157 return;
158 QWidget *topLevelWindow = qt_sizegrip_topLevelWidget(const_cast<QSizeGrip *>(q));
159 if(topLevelWindow && topLevelWindow->isWindow())
160 QWidgetPrivate::qt_mac_update_sizer(topLevelWindow, hide ? -1 : 1);
161}
162#endif
163
164Qt::Corner QSizeGripPrivate::corner() const
165{
166 Q_Q(const QSizeGrip);
167 QWidget *tlw = qt_sizegrip_topLevelWidget(const_cast<QSizeGrip *>(q));
168 const QPoint sizeGripPos = q->mapTo(tlw, QPoint(0, 0));
169 bool isAtBottom = sizeGripPos.y() >= tlw->height() / 2;
170 bool isAtLeft = sizeGripPos.x() <= tlw->width() / 2;
171 if (isAtLeft)
172 return isAtBottom ? Qt::BottomLeftCorner : Qt::TopLeftCorner;
173 else
174 return isAtBottom ? Qt::BottomRightCorner : Qt::TopRightCorner;
175}
176
177/*!
178 \class QSizeGrip
179
180 \brief The QSizeGrip class provides a resize handle for resizing top-level windows.
181
182 \ingroup mainwindow-classes
183 \ingroup basicwidgets
184
185 This widget works like the standard Windows resize handle. In the
186 X11 version this resize handle generally works differently from
187 the one provided by the system if the X11 window manager does not
188 support necessary modern post-ICCCM specifications.
189
190 Put this widget anywhere in a widget tree and the user can use it
191 to resize the top-level window or any widget with the Qt::SubWindow
192 flag set. Generally, this should be in the lower right-hand corner.
193 Note that QStatusBar already uses this widget, so if you have a
194 status bar (e.g., you are using QMainWindow), then you don't need
195 to use this widget explicitly.
196
197 On some platforms the size grip automatically hides itself when the
198 window is shown full screen or maximised.