Qt 4.8
qscrollarea.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qscrollarea.h"
43 #include "private/qscrollarea_p.h"
44 
45 #ifndef QT_NO_SCROLLAREA
46 
47 #include "qscrollbar.h"
48 #include "qlayout.h"
49 #include "qstyle.h"
50 #include "qapplication.h"
51 #include "qvariant.h"
52 #include "qdebug.h"
53 #include "private/qlayoutengine_p.h"
54 
56 
147 {
148  Q_D(QScrollArea);
149  d->viewport->setBackgroundRole(QPalette::NoRole);
150  d->vbar->setSingleStep(20);
151  d->hbar->setSingleStep(20);
152  d->layoutChildren();
153 }
154 
159  : QAbstractScrollArea(dd, parent)
160 {
161  Q_D(QScrollArea);
162  d->viewport->setBackgroundRole(QPalette::NoRole);
163  d->vbar->setSingleStep(20);
164  d->hbar->setSingleStep(20);
165  d->layoutChildren();
166 }
167 
174 {
175 }
176 
178 {
179  Q_Q(QScrollArea);
180  Qt::LayoutDirection dir = q->layoutDirection();
181  QRect scrolled = QStyle::visualRect(dir, viewport->rect(), QRect(QPoint(-hbar->value(), -vbar->value()), widget->size()));
182  QRect aligned = QStyle::alignedRect(dir, alignment, widget->size(), viewport->rect());
183  widget->move(widget->width() < viewport->width() ? aligned.x() : scrolled.x(),
184  widget->height() < viewport->height() ? aligned.y() : scrolled.y());
185 }
186 
188 {
189  Q_Q(QScrollArea);
190  if (!widget)
191  return;
192  QSize p = viewport->size();
193  QSize m = q->maximumViewportSize();
194 
195  QSize min = qSmartMinSize(widget);
196  QSize max = qSmartMaxSize(widget);
197 
198  if (resizable) {
200  QSize p_hfw = p.expandedTo(min).boundedTo(max);
201  int h = widget->heightForWidth( p_hfw.width() );
202  min = QSize(p_hfw.width(), qMax(p_hfw.height(), h));
203  }
204  }
205 
206  if ((resizable && m.expandedTo(min) == m && m.boundedTo(max) == m)
207  || (!resizable && m.expandedTo(widget->size()) == m))
208  p = m; // no scroll bars needed
209 
210  if (resizable)
211  widget->resize(p.expandedTo(min).boundedTo(max));
212  QSize v = widget->size();
213 
214  hbar->setRange(0, v.width() - p.width());
215  hbar->setPageStep(p.width());
216  vbar->setRange(0, v.height() - p.height());
217  vbar->setPageStep(p.height());
218  updateWidgetPosition();
219 
220 }
221 
229 {
230  Q_D(const QScrollArea);
231  return d->widget;
232 }
233 
258 {
259  Q_D(QScrollArea);
260  if (widget == d->widget || !widget)
261  return;
262 
263  delete d->widget;
264  d->widget = 0;
265  d->hbar->setValue(0);
266  d->vbar->setValue(0);
267  if (widget->parentWidget() != d->viewport)
268  widget->setParent(d->viewport);
269  if (!widget->testAttribute(Qt::WA_Resized))
270  widget->resize(widget->sizeHint());
271  d->widget = widget;
272  d->widget->setAutoFillBackground(true);
273  widget->installEventFilter(this);
274  d->widgetSize = QSize();
275  d->updateScrollBars();
276  d->widget->show();
277 
278 }
279 
287 {
288  Q_D(QScrollArea);
289  QWidget *w = d->widget;
290  d->widget = 0;
291  if (w)
292  w->setParent(0);
293  return w;
294 }
295 
300 {
301  Q_D(QScrollArea);
302  if (e->type() == QEvent::StyleChange || e->type() == QEvent::LayoutRequest) {
303  d->updateScrollBars();
304  }
305 #ifdef QT_KEYPAD_NAVIGATION
306  else if (QApplication::keypadNavigationEnabled()) {
307  if (e->type() == QEvent::Show)
309  else if (e->type() == QEvent::Hide)
311  }
312 #endif
313  return QAbstractScrollArea::event(e);
314 }
315 
316 
321 {
322  Q_D(QScrollArea);
323 #ifdef QT_KEYPAD_NAVIGATION
324  if (d->widget && o != d->widget && e->type() == QEvent::FocusIn
325  && QApplication::keypadNavigationEnabled()) {
326  if (o->isWidgetType())
327  ensureWidgetVisible(static_cast<QWidget *>(o));
328  }
329 #endif
330  if (o == d->widget && e->type() == QEvent::Resize)
331  d->updateScrollBars();
332 
333  return false;
334 }
335 
340 {
341  Q_D(QScrollArea);
342  d->updateScrollBars();
343 
344 }
345 
346 
350 {
351  Q_D(QScrollArea);
352  if (!d->widget)
353  return;
354  d->updateWidgetPosition();
355 }
356 
357 
375 bool QScrollArea::widgetResizable() const
376 {
377  Q_D(const QScrollArea);
378  return d->resizable;
379 }
380 
382 {
383  Q_D(QScrollArea);
384  d->resizable = resizable;
385  updateGeometry();
386  d->updateScrollBars();
387 }
388 
393 {
394  Q_D(const QScrollArea);
395  int f = 2 * d->frameWidth;
396  QSize sz(f, f);
397  int h = fontMetrics().height();
398  if (d->widget) {
399  if (!d->widgetSize.isValid())
400  d->widgetSize = d->resizable ? d->widget->sizeHint() : d->widget->size();
401  sz += d->widgetSize;
402  } else {
403  sz += QSize(12 * h, 8 * h);
404  }
405  if (d->vbarpolicy == Qt::ScrollBarAlwaysOn)
406  sz.setWidth(sz.width() + d->vbar->sizeHint().width());
407  if (d->hbarpolicy == Qt::ScrollBarAlwaysOn)
408  sz.setHeight(sz.height() + d->hbar->sizeHint().height());
409  return sz.boundedTo(QSize(36 * h, 24 * h));
410 }
411 
412 
413 
418 {
419  if (QWidget::focusNextPrevChild(next)) {
420  if (QWidget *fw = focusWidget())
422  return true;
423  }
424  return false;
425 }
426 
433 void QScrollArea::ensureVisible(int x, int y, int xmargin, int ymargin)
434 {
435  Q_D(QScrollArea);
436 
437  int logicalX = QStyle::visualPos(layoutDirection(), d->viewport->rect(), QPoint(x, y)).x();
438 
439  if (logicalX - xmargin < d->hbar->value()) {
440  d->hbar->setValue(qMax(0, logicalX - xmargin));
441  } else if (logicalX > d->hbar->value() + d->viewport->width() - xmargin) {
442  d->hbar->setValue(qMin(logicalX - d->viewport->width() + xmargin, d->hbar->maximum()));
443  }
444 
445  if (y - ymargin < d->vbar->value()) {
446  d->vbar->setValue(qMax(0, y - ymargin));
447  } else if (y > d->vbar->value() + d->viewport->height() - ymargin) {
448  d->vbar->setValue(qMin(y - d->viewport->height() + ymargin, d->vbar->maximum()));
449  }
450 }
451 
466 void QScrollArea::ensureWidgetVisible(QWidget *childWidget, int xmargin, int ymargin)
467 {
468  Q_D(QScrollArea);
469 
470  if (!d->widget->isAncestorOf(childWidget))
471  return;
472 
473  const QRect microFocus = childWidget->inputMethodQuery(Qt::ImMicroFocus).toRect();
474  const QRect defaultMicroFocus =
475  childWidget->QWidget::inputMethodQuery(Qt::ImMicroFocus).toRect();
476  QRect focusRect = (microFocus != defaultMicroFocus)
477  ? QRect(childWidget->mapTo(d->widget, microFocus.topLeft()), microFocus.size())
478  : QRect(childWidget->mapTo(d->widget, QPoint(0,0)), childWidget->size());
479  const QRect visibleRect(-d->widget->pos(), d->viewport->size());
480 
481  if (visibleRect.contains(focusRect))
482  return;
483 
484  focusRect.adjust(-xmargin, -ymargin, xmargin, ymargin);
485 
486  if (focusRect.width() > visibleRect.width())
487  d->hbar->setValue(focusRect.center().x() - d->viewport->width() / 2);
488  else if (focusRect.right() > visibleRect.right())
489  d->hbar->setValue(focusRect.right() - d->viewport->width());
490  else if (focusRect.left() < visibleRect.left())
491  d->hbar->setValue(focusRect.left());
492 
493  if (focusRect.height() > visibleRect.height())
494  d->vbar->setValue(focusRect.center().y() - d->viewport->height() / 2);
495  else if (focusRect.bottom() > visibleRect.bottom())
496  d->vbar->setValue(focusRect.bottom() - d->viewport->height());
497  else if (focusRect.top() < visibleRect.top())
498  d->vbar->setValue(focusRect.top());
499 }
500 
501 
515 {
516  Q_D(QScrollArea);
517  d->alignment = alignment;
518  if (d->widget)
519  d->updateWidgetPosition();
520 }
521 
522 Qt::Alignment QScrollArea::alignment() const
523 {
524  Q_D(const QScrollArea);
525  return d->alignment;
526 }
527 
529 
530 #endif // QT_NO_SCROLLAREA
double d
Definition: qnumeric_p.h:62
static QRect alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment, const QSize &size, const QRect &rectangle)
Returns a new rectangle of the specified size that is aligned to the given rectangle according to the...
Definition: qstyle.cpp:2120
QWidget * parentWidget() const
Returns the parent of this widget, or 0 if it does not have any parent widget.
Definition: qwidget.h:1035
QWidget * focusWidget() const
Returns the last child of this widget that setFocus had been called on.
Definition: qwidget.cpp:6863
Qt::Alignment alignment() const
virtual int heightForWidth(int) const
Returns the preferred height for this widget, given the width w.
Definition: qwidget.cpp:10241
int y() const
~QScrollArea()
Destroys the scroll area and its child widget.
void resizeEvent(QResizeEvent *)
Reimplemented Function
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void setParent(QWidget *parent)
Sets the parent of the widget to parent, and resets the window flags.
Definition: qwidget.cpp:10479
Q_GUI_EXPORT QSize qSmartMinSize(const QSize &sizeHint, const QSize &minSizeHint, const QSize &minSize, const QSize &maxSize, const QSizePolicy &sizePolicy)
static QPoint visualPos(Qt::LayoutDirection direction, const QRect &boundingRect, const QPoint &logicalPos)
Returns the given logicalPosition converted to screen coordinates based on the specified direction...
Definition: qstyle.cpp:2109
int width
the width of the widget excluding any window frame
Definition: qwidget.h:166
QPoint mapTo(QWidget *, const QPoint &) const
Translates the widget coordinate pos to the coordinate system of parent.
Definition: qwidget.cpp:4409
Q_GUI_EXPORT QSize qSmartMaxSize(const QSize &sizeHint, const QSize &minSize, const QSize &maxSize, const QSizePolicy &sizePolicy, Qt::Alignment align)
void removeEventFilter(QObject *)
Removes an event filter object obj from this object.
Definition: qobject.cpp:2099
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
QSize expandedTo(const QSize &) const
Returns a size holding the maximum width and height of this size and the given otherSize.
Definition: qsize.h:187
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
bool focusNextPrevChild(bool next)
Reimplemented Function
The QAbstractScrollArea widget provides a scrolling area with on-demand scroll bars.
virtual QVariant inputMethodQuery(Qt::InputMethodQuery) const
This method is only relevant for input widgets.
Definition: qwidget.cpp:9683
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
void setHeight(int h)
Sets the height to the given height.
Definition: qsize.h:135
virtual bool hasHeightForWidth() const
Returns true if this layout&#39;s preferred height depends on its width; otherwise returns false...
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define Q_D(Class)
Definition: qglobal.h:2482
QSize boundedTo(const QSize &) const
Returns a size holding the minimum width and height of this size and the given otherSize.
Definition: qsize.h:192
The QScrollArea class provides a scrolling view onto another widget.
Definition: qscrollarea.h:57
QWidget * widget() const
Returns the scroll area&#39;s widget, or 0 if there is none.
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
#define Q_Q(Class)
Definition: qglobal.h:2483
void setWidth(int w)
Sets the width to the given width.
Definition: qsize.h:132
bool eventFilter(QObject *, QEvent *)
Reimplemented Function
QWidget * viewport() const
Returns the viewport widget.
void scrollContentsBy(int dx, int dy)
This virtual handler is called when the scroll bars are moved by dx, dy, and consequently the viewpor...
void setWidgetResizable(bool resizable)
int width() const
Returns the width.
Definition: qsize.h:126
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
bool hasHeightForWidth() const
Definition: qsizepolicy.h:136
int height
the height of the widget excluding any window frame
Definition: qwidget.h:167
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition: qwidget.h:1041
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
void adjust(int x1, int y1, int x2, int y2)
Adds dx1, dy1, dx2 and dy2 respectively to the existing coordinates of the rectangle.
Definition: qrect.h:434
LayoutDirection
Definition: qnamespace.h:1580
QFontMetrics fontMetrics() const
Returns the font metrics for the widget&#39;s current font.
Definition: qwidget.h:984
The QResizeEvent class contains event parameters for resize events.
Definition: qevent.h:349
QSize size
the size of the widget excluding any window frame
Definition: qwidget.h:165
void ensureVisible(int x, int y, int xmargin=50, int ymargin=50)
Scrolls the contents of the scroll area so that the point (x, y) is visible inside the region of the ...
QWidget * takeWidget()
Removes the scroll area&#39;s widget, and passes ownership of the widget to the caller.
QPoint center() const
Returns the center point of the rectangle.
Definition: qrect.h:300
void setAlignment(Qt::Alignment)
bool isWidgetType() const
Returns true if the object is a widget; otherwise returns false.
Definition: qobject.h:146
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
static QRect visualRect(Qt::LayoutDirection direction, const QRect &boundingRect, const QRect &logicalRect)
Returns the given logicalRectangle converted to screen coordinates based on the specified direction...
Definition: qstyle.cpp:2087
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
int x() const
void resize(int w, int h)
This corresponds to resize(QSize(w, h)).
Definition: qwidget.h:1014
Qt::LayoutDirection layoutDirection() const
QRect rect
the internal geometry of the widget excluding any window frame
Definition: qwidget.h:168
static QCoreApplication * instance()
Returns a pointer to the application&#39;s QCoreApplication (or QApplication) instance.
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
QRect toRect() const
Returns the variant as a QRect if the variant has type() Rect ; otherwise returns an invalid QRect...
Definition: qvariant.cpp:2416
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
QSizePolicy sizePolicy
the default layout behavior of the widget
Definition: qwidget.h:171
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
void installEventFilter(QObject *)
Installs an event filter filterObj on this object.
Definition: qobject.cpp:2070
virtual bool focusNextPrevChild(bool next)
Finds a new widget to give the keyboard focus to, as appropriate for Tab and Shift+Tab, and returns true if it can find a new widget, or false if it can&#39;t.
Definition: qwidget.cpp:6836
int height() const
Returns the height.
Definition: qsize.h:129
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
bool widgetResizable() const
void setWidget(QWidget *widget)
Sets the scroll area&#39;s widget.
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
QSize sizeHint() const
Reimplemented Function
bool event(QEvent *)
Reimplemented Function
QScrollArea(QWidget *parent=0)
Constructs an empty scroll area with the given parent.
QLayout * layout() const
Returns the layout manager that is installed on this widget, or 0 if no layout manager is installed...
Definition: qwidget.cpp:10073
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
QSize sizeHint
the recommended size for the widget
Definition: qwidget.h:195
bool event(QEvent *)
Reimplemented Function
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
void updateGeometry()
Notifies the layout system that this widget has changed and may need to change geometry.
Definition: qwidget.cpp:10372
int height() const
Returns the height of the font.
void ensureWidgetVisible(QWidget *childWidget, int xmargin=50, int ymargin=50)
Scrolls the contents of the scroll area so that the childWidget of QScrollArea::widget() is visible i...
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
void move(int x, int y)
This corresponds to move(QPoint(x, y)).
Definition: qwidget.h:1011
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288