source: trunk/src/gui/widgets/qfocusframe.cpp@ 64

Last change on this file since 64 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 7.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qfocusframe.h"
43#include "qstyle.h"
44#include "qbitmap.h"
45#include "qstylepainter.h"
46#include "qstyleoption.h"
47#include "qdebug.h"
48#include <private/qwidget_p.h>
49
50QT_BEGIN_NAMESPACE
51
52class QFocusFramePrivate : public QWidgetPrivate
53{
54 Q_DECLARE_PUBLIC(QFocusFrame)
55 QWidget *widget;
56
57public:
58 QFocusFramePrivate() {
59 widget = 0;
60 sendChildEvents = false;
61 }
62 void updateSize();
63 void update();
64};
65
66void QFocusFramePrivate::update()
67{
68 Q_Q(QFocusFrame);
69 q->setParent(widget->parentWidget());
70 updateSize();
71 if (q->parentWidget()->rect().intersects(q->geometry())) {
72 if (q->style()->styleHint(QStyle::SH_FocusFrame_AboveWidget, 0, q))
73 q->raise();
74 else
75 q->stackUnder(widget);
76 q->show();
77 } else {
78 q->hide();
79 }
80}
81
82void QFocusFramePrivate::updateSize()
83{
84 Q_Q(QFocusFrame);
85 int vmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameVMargin),
86 hmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameHMargin);
87 QRect geom(widget->x()-hmargin, widget->y()-vmargin,
88 widget->width()+(hmargin*2), widget->height()+(vmargin*2));
89 if(q->geometry() == geom)
90 return;
91
92 q->setGeometry(geom);
93 QStyleHintReturnMask mask;
94 QStyleOption opt;
95 q->initStyleOption(&opt);
96 if (q->style()->styleHint(QStyle::SH_FocusFrame_Mask, &opt, q, &mask))
97 q->setMask(mask.region);
98}
99
100/*!
101 Initialize \a option with the values from this QFocusFrame. This method is useful
102 for subclasses when they need a QStyleOption, but don't want to fill
103 in all the information themselves.
104
105 \sa QStyleOption::initFrom()
106*/
107void QFocusFrame::initStyleOption(QStyleOption *option) const
108{
109 if (!option)
110 return;
111
112 option->initFrom(this);
113}
114
115/*!
116 \class QFocusFrame
117 \brief The QFocusFrame widget provides a focus frame which can be
118 outside of a widget's normal paintable area.
119
120 \ingroup basicwidgets
121 \mainclass
122
123 Normally an application will not need to create its own
124 QFocusFrame as QStyle will handle this detail for
125 you. A style writer can optionally use a QFocusFrame to have a
126 focus area outside of the widget's paintable geometry. In this way
127 space need not be reserved for the widget to have focus but only
128 set on a QWidget with QFocusFrame::setWidget. It is, however,
129 legal to create your own QFocusFrame on a custom widget and set
130 its geometry manually via QWidget::setGeometry however you will
131 not get auto-placement when the focused widget changes size or
132 placement.
133*/
134
135/*!
136 Constructs a QFocusFrame.
137
138 The focus frame will not monitor \a parent for updates but rather
139 can be placed manually or by using QFocusFrame::setWidget. A
140 QFocusFrame sets Qt::WA_NoChildEventsForParent attribute; as a
141 result the parent will not receive a QEvent::ChildInserted event,
142 this will make it possible to manually set the geometry of the
143 QFocusFrame inside of a QSplitter or other child event monitoring
144 widget.
145
146 \sa QFocusFrame::setWidget()
147*/
148
149QFocusFrame::QFocusFrame(QWidget *parent)
150 : QWidget(*new QFocusFramePrivate, parent, 0)
151{
152 setAttribute(Qt::WA_TransparentForMouseEvents);
153 setFocusPolicy(Qt::NoFocus);
154 setAttribute(Qt::WA_NoChildEventsForParent, true);
155 setAttribute(Qt::WA_AcceptDrops, style()->styleHint(QStyle::SH_FocusFrame_AboveWidget, 0, this));
156}
157
158/*!
159 Destructor.
160*/
161
162QFocusFrame::~QFocusFrame()
163{
164}
165
166/*!
167 QFocusFrame will track changes to \a widget and resize itself automatically.
168 If the monitored widget's parent changes, QFocusFrame will follow the widget
169 and place itself around the widget automatically. If the monitored widget is deleted,
170 QFocusFrame will set it to zero.
171
172 \sa QFocusFrame::widget()
173*/
174
175void
176QFocusFrame::setWidget(QWidget *widget)
177{
178 Q_D(QFocusFrame);
179 if(widget == d->widget)
180 return;
181
182 if(d->widget)
183 d->widget->removeEventFilter(this);
184 if(widget && !widget->isWindow() && widget->parentWidget()->windowType() != Qt::SubWindow) {
185 d->widget = widget;
186 widget->installEventFilter(this);
187 d->update();
188 } else {
189 d->widget = 0;
190 hide();
191 }
192}
193
194/*!
195 Returns the currently monitored widget for automatically resize and
196 update.
197
198 \sa QFocusFrame::setWidget()
199*/
200
201QWidget *
202QFocusFrame::widget() const
203{
204 Q_D(const QFocusFrame);
205 return d->widget;
206}
207
208
209/*! \reimp */
210void
211QFocusFrame::paintEvent(QPaintEvent *)
212{
213 QStylePainter p(this);
214 QStyleOption option;
215 initStyleOption(&option);
216 p.drawControl(QStyle::CE_FocusFrame, option);
217}
218
219
220/*! \reimp */
221bool
222QFocusFrame::eventFilter(QObject *o, QEvent *e)
223{
224 Q_D(QFocusFrame);
225 if(o == d->widget) {
226 switch(e->type()) {
227 case QEvent::Move:
228 case QEvent::Resize:
229 d->updateSize();
230 break;
231 case QEvent::Hide:
232 case QEvent::StyleChange:
233 hide();
234 break;
235 case QEvent::ParentChange:
236 d->update();
237 break;
238 case QEvent::Show:
239 d->update();
240 show();
241 break;
242 case QEvent::PaletteChange:
243 setPalette(d->widget->palette());
244 break;
245 case QEvent::ZOrderChange:
246 if (style()->styleHint(QStyle::SH_FocusFrame_AboveWidget, 0, this))
247 raise();
248 else
249 stackUnder(d->widget);
250 break;
251 case QEvent::Destroy:
252 setWidget(0);
253 break;
254 default:
255 break;
256 }
257 }
258 return false;
259}
260
261/*! \reimp */
262bool QFocusFrame::event(QEvent *e)
263{
264 return QWidget::event(e);
265}
266
267QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.