6#if QT_CONFIG(scrollarea)
9#include "qapplication.h"
11#include "qstyleoption.h"
14#include "qboxlayout.h"
17#if QT_CONFIG(itemviews)
18#include "qheaderview.h"
23#include "qabstractscrollarea_p.h"
24#include "qscrollbar_p.h"
27#include <private/qapplication_p.h>
30# include <qt_windows.h>
35using namespace Qt::StringLiterals;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
129QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate()
130 :hbar(
nullptr), vbar(
nullptr), vbarpolicy(Qt::ScrollBarAsNeeded), hbarpolicy(Qt::ScrollBarAsNeeded),
131 shownOnce(
false), inResize(
false), sizeAdjustPolicy(QAbstractScrollArea::AdjustIgnored),
132 viewport(
nullptr), cornerWidget(
nullptr), left(0), top(0), right(0), bottom(0),
133 xoffset(0), yoffset(0), viewportFilter(
nullptr)
137QAbstractScrollAreaPrivate::~QAbstractScrollAreaPrivate()
141QAbstractScrollAreaScrollBarContainer::QAbstractScrollAreaScrollBarContainer(Qt::Orientation orientation, QWidget *parent)
142 :QWidget(parent), scrollBar(
new QScrollBar(orientation,
this)),
143 layout(
new QBoxLayout(orientation == Qt::Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom)),
144 orientation(orientation)
147 layout->setContentsMargins(QMargins());
148 layout->setSpacing(0);
149 layout->addWidget(scrollBar);
150 layout->setSizeConstraint(QLayout::SetMaximumSize);
154
155
156void QAbstractScrollAreaScrollBarContainer::addWidget(QWidget *widget, LogicalPosition position)
158 QSizePolicy policy = widget->sizePolicy();
159 if (orientation == Qt::Vertical)
160 policy.setHorizontalPolicy(QSizePolicy::Ignored);
162 policy.setVerticalPolicy(QSizePolicy::Ignored);
163 widget->setSizePolicy(policy);
164 widget->setParent(
this);
166 const int insertIndex = (position & LogicalLeft) ? 0 : scrollBarLayoutIndex() + 1;
167 layout->insertWidget(insertIndex, widget);
171
172
173
174QWidgetList QAbstractScrollAreaScrollBarContainer::widgets(LogicalPosition position)
177 const int scrollBarIndex = scrollBarLayoutIndex();
178 if (position == LogicalLeft) {
179 list.reserve(scrollBarIndex);
180 for (
int i = 0; i < scrollBarIndex; ++i)
181 list.append(layout->itemAt(i)->widget());
182 }
else if (position == LogicalRight) {
183 const int layoutItemCount = layout->count();
184 list.reserve(layoutItemCount - (scrollBarIndex + 1));
185 for (
int i = scrollBarIndex + 1; i < layoutItemCount; ++i)
186 list.append(layout->itemAt(i)->widget());
192
193
194
195
196
197int QAbstractScrollAreaScrollBarContainer::scrollBarLayoutIndex()
const
199 const int layoutItemCount = layout->count();
200 for (
int i = 0; i < layoutItemCount; ++i) {
201 if (qobject_cast<QScrollBar *>(layout->itemAt(i)->widget()))
208
209void QAbstractScrollAreaPrivate::replaceScrollBar(QScrollBar *scrollBar,
210 Qt::Orientation orientation)
212 Q_Q(QAbstractScrollArea);
214 QAbstractScrollAreaScrollBarContainer *container = scrollBarContainers[orientation];
215 bool horizontal = (orientation == Qt::Horizontal);
216 QScrollBar *oldBar = horizontal ? hbar : vbar;
221 scrollBar->setParent(container);
222 container->scrollBar = scrollBar;
223 container->layout->removeWidget(oldBar);
224 container->layout->insertWidget(0, scrollBar);
225 scrollBar->setVisible(oldBar->isVisibleTo(container));
226 scrollBar->setInvertedAppearance(oldBar->invertedAppearance());
227 scrollBar->setInvertedControls(oldBar->invertedControls());
228 scrollBar->setRange(oldBar->minimum(), oldBar->maximum());
229 scrollBar->setOrientation(oldBar->orientation());
230 scrollBar->setPageStep(oldBar->pageStep());
231 scrollBar->setSingleStep(oldBar->singleStep());
232 scrollBar->d_func()->viewMayChangeSingleStep = oldBar->d_func()->viewMayChangeSingleStep;
233 scrollBar->setSliderDown(oldBar->isSliderDown());
234 scrollBar->setSliderPosition(oldBar->sliderPosition());
235 scrollBar->setTracking(oldBar->hasTracking());
236 scrollBar->setValue(oldBar->value());
237 scrollBar->installEventFilter(q);
238 oldBar->removeEventFilter(q);
241 QObject::connect(scrollBar, SIGNAL(valueChanged(
int)),
242 q, horizontal ? SLOT(_q_hslide(
int)) : SLOT(_q_vslide(
int)));
243 QObject::connect(scrollBar, SIGNAL(rangeChanged(
int,
int)),
244 q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);
247void QAbstractScrollAreaPrivate::init()
249 Q_Q(QAbstractScrollArea);
250 viewport =
new QWidget(q);
251 viewport->setObjectName(
"qt_scrollarea_viewport"_L1);
252 viewport->setBackgroundRole(QPalette::Base);
253 viewport->setAutoFillBackground(
true);
254 scrollBarContainers[Qt::Horizontal] =
new QAbstractScrollAreaScrollBarContainer(Qt::Horizontal, q);
255 scrollBarContainers[Qt::Horizontal]->setObjectName(
"qt_scrollarea_hcontainer"_L1);
256 hbar = scrollBarContainers[Qt::Horizontal]->scrollBar;
258 scrollBarContainers[Qt::Horizontal]->setVisible(
false);
259 hbar->installEventFilter(q);
260 QObject::connect(hbar, SIGNAL(valueChanged(
int)), q, SLOT(_q_hslide(
int)));
261 QObject::connect(hbar, SIGNAL(rangeChanged(
int,
int)), q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);
262 scrollBarContainers[Qt::Vertical] =
new QAbstractScrollAreaScrollBarContainer(Qt::Vertical, q);
263 scrollBarContainers[Qt::Vertical]->setObjectName(
"qt_scrollarea_vcontainer"_L1);
264 vbar = scrollBarContainers[Qt::Vertical]->scrollBar;
266 scrollBarContainers[Qt::Vertical]->setVisible(
false);
267 vbar->installEventFilter(q);
268 QObject::connect(vbar, SIGNAL(valueChanged(
int)), q, SLOT(_q_vslide(
int)));
269 QObject::connect(vbar, SIGNAL(rangeChanged(
int,
int)), q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);
270 viewportFilter.reset(
new QAbstractScrollAreaFilter(
this));
271 viewport->installEventFilter(viewportFilter.data());
272 viewport->setFocusProxy(q);
273 q->setFocusPolicy(Qt::StrongFocus);
274 q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
275 q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
278# ifndef QT_NO_GESTURES
279 viewport->grabGesture(Qt::PanGesture);
284void QAbstractScrollAreaPrivate::layoutChildren()
288 layoutChildren_helper(&needH, &needV);
292 layoutChildren_helper(&needH, &needV);
295void QAbstractScrollAreaPrivate::layoutChildren_helper(
bool *needHorizontalScrollbar,
bool *needVerticalScrollbar)
297 Q_Q(QAbstractScrollArea);
298 QStyleOptionSlider barOpt;
300 hbar->initStyleOption(&barOpt);
301 bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &barOpt, hbar);
302 bool needh = *needHorizontalScrollbar || ((hbarpolicy != Qt::ScrollBarAlwaysOff) && ((hbarpolicy == Qt::ScrollBarAlwaysOn && !htransient)
303 || ((hbarpolicy == Qt::ScrollBarAsNeeded || htransient)
304 && hbar->minimum() < hbar->maximum() && !hbar->sizeHint().isEmpty())));
305 const int hscrollOverlap = hbar->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarOverlap, &barOpt, hbar);
307 vbar->initStyleOption(&barOpt);
308 bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &barOpt, vbar);
309 bool needv = *needVerticalScrollbar || ((vbarpolicy != Qt::ScrollBarAlwaysOff) && ((vbarpolicy == Qt::ScrollBarAlwaysOn && !vtransient)
310 || ((vbarpolicy == Qt::ScrollBarAsNeeded || vtransient)
311 && vbar->minimum() < vbar->maximum() && !vbar->sizeHint().isEmpty())));
312 const int vscrollOverlap = vbar->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarOverlap, &barOpt, vbar);
317 const int hsbExt = hbar->sizeHint().height();
318 const int vsbExt = vbar->sizeHint().width();
319 const QPoint extPoint(vsbExt, hsbExt);
320 const QSize extSize(vsbExt, hsbExt);
322 const QRect widgetRect = q->rect();
324 const bool hasCornerWidget = (cornerWidget !=
nullptr);
326 QPoint cornerOffset((needv && vscrollOverlap == 0) ? vsbExt : 0, (needh && hscrollOverlap == 0) ? hsbExt : 0);
332 if ((frameStyle != QFrame::NoFrame) &&
333 q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt, q)) {
334 controlsRect = widgetRect;
335 const int spacing = q->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt, q);
336 const QPoint cornerExtra(needv ? spacing + vscrollOverlap : 0, needh ? spacing + hscrollOverlap : 0);
337 QRect frameRect = widgetRect;
338 frameRect.adjust(0, 0, -cornerOffset.x() - cornerExtra.x(), -cornerOffset.y() - cornerExtra.y());
339 q->setFrameRect(QStyle::visualRect(opt.direction, opt.rect, frameRect));
343 viewportRect = QStyle::visualRect(opt.direction, opt.rect, q->contentsRect());
345 q->setFrameRect(QStyle::visualRect(opt.direction, opt.rect, widgetRect));
346 controlsRect = q->contentsRect();
347 viewportRect = QRect(controlsRect.topLeft(), controlsRect.bottomRight() - cornerOffset);
350 cornerOffset = QPoint(needv ? vsbExt : 0, needh ? hsbExt : 0);
354 if (hasCornerWidget && ((needv && vscrollOverlap == 0) || (needh && hscrollOverlap == 0)))
355 cornerOffset = extPoint;
359 const QPoint cornerPoint(controlsRect.bottomRight() + QPoint(1, 1) - cornerOffset);
363 if (needv && needh && !hasCornerWidget && hscrollOverlap == 0 && vscrollOverlap == 0)
364 cornerPaintingRect = QStyle::visualRect(opt.direction, opt.rect, QRect(cornerPoint, extSize));
366 cornerPaintingRect = QRect();
369 int vHeaderRight = 0;
370 int hHeaderBottom = 0;
371#if QT_CONFIG(itemviews)
372 if ((vscrollOverlap > 0 && needv) || (hscrollOverlap > 0 && needh)) {
373 const QList<QHeaderView *> headers = q->findChildren<QHeaderView*>();
374 if (headers.size() <= 2) {
375 for (
const QHeaderView *header : headers) {
376 const QRect geo = header->geometry();
377 if (header->orientation() == Qt::Vertical && header->isVisible() && QStyle::visualRect(opt.direction, opt.rect, geo).left() <= opt.rect.width() / 2)
378 vHeaderRight = QStyle::visualRect(opt.direction, opt.rect, geo).right();
379 else if (header->orientation() == Qt::Horizontal && header->isVisible() && geo.top() <= q->frameWidth())
380 hHeaderBottom = geo.bottom();
386 QRect horizontalScrollBarRect(QPoint(controlsRect.left() + vHeaderRight, cornerPoint.y()), QPoint(cornerPoint.x() - 1, controlsRect.bottom()));
388 if (!hasCornerWidget && htransient)
389 horizontalScrollBarRect.adjust(0, 0, cornerOffset.x(), 0);
390 scrollBarContainers[Qt::Horizontal]->setGeometry(QStyle::visualRect(opt.direction, opt.rect, horizontalScrollBarRect));
391 scrollBarContainers[Qt::Horizontal]->raise();
395 QRect verticalScrollBarRect (QPoint(cornerPoint.x(), controlsRect.top() + hHeaderBottom), QPoint(controlsRect.right(), cornerPoint.y() - 1));
396 if (!hasCornerWidget && vtransient)
397 verticalScrollBarRect.adjust(0, 0, 0, cornerOffset.y());
398 scrollBarContainers[Qt::Vertical]->setGeometry(QStyle::visualRect(opt.direction, opt.rect, verticalScrollBarRect));
399 scrollBarContainers[Qt::Vertical]->raise();
403 const QRect cornerWidgetRect(cornerPoint, controlsRect.bottomRight());
404 cornerWidget->setGeometry(QStyle::visualRect(opt.direction, opt.rect, cornerWidgetRect));
407 scrollBarContainers[Qt::Horizontal]->setVisible(needh);
408 scrollBarContainers[Qt::Vertical]->setVisible(needv);
410 if (q->isRightToLeft())
411 viewportRect.adjust(right, top, -left, -bottom);
413 viewportRect.adjust(left, top, -right, -bottom);
414 viewportRect = QStyle::visualRect(opt.direction, opt.rect, viewportRect);
415 viewportRect.translate(-overshoot);
416 viewport->setGeometry(viewportRect);
418 *needHorizontalScrollbar = needh;
419 *needVerticalScrollbar = needv;
423
424
425
426
427
428
429
430
431
432
436
437
438
439
440QAbstractScrollArea::QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget *parent)
443 Q_D(QAbstractScrollArea);
447 d->viewportFilter.reset();
453
454
455
456
457QAbstractScrollArea::QAbstractScrollArea(QWidget *parent)
458 :QFrame(*
new QAbstractScrollAreaPrivate, parent)
460 Q_D(QAbstractScrollArea);
464 d->viewportFilter.reset();
471
472
473QAbstractScrollArea::~QAbstractScrollArea()
475 Q_D(QAbstractScrollArea);
477 d->viewportFilter.reset();
482
483
484
485
486
487
488
489
490
491void QAbstractScrollArea::setViewport(QWidget *widget)
493 Q_D(QAbstractScrollArea);
494 if (widget != d->viewport) {
495 QWidget *oldViewport = d->viewport;
497 widget =
new QWidget;
498 d->viewport = widget;
499 d->viewport->setParent(
this);
500 d->viewport->setFocusProxy(
this);
501 d->viewport->installEventFilter(d->viewportFilter.data());
502#ifndef QT_NO_GESTURES
503 d->viewport->grabGesture(Qt::PanGesture);
507 QWidgetPrivate::get(d->viewport)->initializeViewportFramebuffer();
511 setupViewport(widget);
517
518
519
520
521
522
523
524QWidget *QAbstractScrollArea::viewport()
const
526 Q_D(
const QAbstractScrollArea);
532
533
534
535QSize QAbstractScrollArea::maximumViewportSize()
const
537 Q_D(
const QAbstractScrollArea);
538 int f = 2 * d->frameWidth;
539 QSize max = size() - QSize(f + d->left + d->right, f + d->top + d->bottom);
541 if (d->vbarpolicy == Qt::ScrollBarAlwaysOn)
542 max.rwidth() -= d->vbar->sizeHint().width();
543 if (d->hbarpolicy == Qt::ScrollBarAlwaysOn)
544 max.rheight() -= d->hbar->sizeHint().height();
549
550
551
552
553
554
555
557Qt::ScrollBarPolicy QAbstractScrollArea::verticalScrollBarPolicy()
const
559 Q_D(
const QAbstractScrollArea);
560 return d->vbarpolicy;
563void QAbstractScrollArea::setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy)
565 Q_D(QAbstractScrollArea);
566 const Qt::ScrollBarPolicy oldPolicy = d->vbarpolicy;
567 d->vbarpolicy = policy;
570 if (oldPolicy != d->vbarpolicy)
571 d->scrollBarPolicyChanged(Qt::Vertical, d->vbarpolicy);
576
577
578
579
580QScrollBar *QAbstractScrollArea::verticalScrollBar()
const
582 Q_D(
const QAbstractScrollArea);
587
588
589
590
591
592
593
594
595
596
597
598void QAbstractScrollArea::setVerticalScrollBar(QScrollBar *scrollBar)
600 Q_D(QAbstractScrollArea);
601 if (Q_UNLIKELY(!scrollBar)) {
602 qWarning(
"QAbstractScrollArea::setVerticalScrollBar: Cannot set a null scroll bar");
606 d->replaceScrollBar(scrollBar, Qt::Vertical);
610
611
612
613
614
615
616
618Qt::ScrollBarPolicy QAbstractScrollArea::horizontalScrollBarPolicy()
const
620 Q_D(
const QAbstractScrollArea);
621 return d->hbarpolicy;
624void QAbstractScrollArea::setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy)
626 Q_D(QAbstractScrollArea);
627 const Qt::ScrollBarPolicy oldPolicy = d->hbarpolicy;
628 d->hbarpolicy = policy;
631 if (oldPolicy != d->hbarpolicy)
632 d->scrollBarPolicyChanged(Qt::Horizontal, d->hbarpolicy);
636
637
638
639
640QScrollBar *QAbstractScrollArea::horizontalScrollBar()
const
642 Q_D(
const QAbstractScrollArea);
647
648
649
650
651
652
653
654
655
656
657
658
659void QAbstractScrollArea::setHorizontalScrollBar(QScrollBar *scrollBar)
661 Q_D(QAbstractScrollArea);
662 if (Q_UNLIKELY(!scrollBar)) {
663 qWarning(
"QAbstractScrollArea::setHorizontalScrollBar: Cannot set a null scroll bar");
667 d->replaceScrollBar(scrollBar, Qt::Horizontal);
671
672
673
674
675
676
677QWidget *QAbstractScrollArea::cornerWidget()
const
679 Q_D(
const QAbstractScrollArea);
680 return d->cornerWidget;
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709void QAbstractScrollArea::setCornerWidget(QWidget *widget)
711 Q_D(QAbstractScrollArea);
712 QWidget* oldWidget = d->cornerWidget;
713 if (oldWidget != widget) {
716 d->cornerWidget = widget;
718 if (widget && widget->parentWidget() !=
this)
719 widget->setParent(
this);
725 d->cornerWidget = widget;
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762void QAbstractScrollArea::addScrollBarWidget(QWidget *widget, Qt::Alignment alignment)
764 Q_D(QAbstractScrollArea);
766 if (widget ==
nullptr)
769 const Qt::Orientation scrollBarOrientation
770 = ((alignment & Qt::AlignLeft) || (alignment & Qt::AlignRight)) ? Qt::Horizontal : Qt::Vertical;
771 const QAbstractScrollAreaScrollBarContainer::LogicalPosition position
772 = ((alignment & Qt::AlignRight) || (alignment & Qt::AlignBottom))
773 ? QAbstractScrollAreaScrollBarContainer::LogicalRight : QAbstractScrollAreaScrollBarContainer::LogicalLeft;
774 d->scrollBarContainers[scrollBarOrientation]->addWidget(widget, position);
776 if (isHidden() ==
false)
781
782
783
784
785
786
787QWidgetList QAbstractScrollArea::scrollBarWidgets(Qt::Alignment alignment)
789 Q_D(QAbstractScrollArea);
793 if (alignment & Qt::AlignLeft)
794 list += d->scrollBarContainers[Qt::Horizontal]->widgets(QAbstractScrollAreaScrollBarContainer::LogicalLeft);
795 if (alignment & Qt::AlignRight)
796 list += d->scrollBarContainers[Qt::Horizontal]->widgets(QAbstractScrollAreaScrollBarContainer::LogicalRight);
797 if (alignment & Qt::AlignTop)
798 list += d->scrollBarContainers[Qt::Vertical]->widgets(QAbstractScrollAreaScrollBarContainer::LogicalLeft);
799 if (alignment & Qt::AlignBottom)
800 list += d->scrollBarContainers[Qt::Vertical]->widgets(QAbstractScrollAreaScrollBarContainer::LogicalRight);
806
807
808
809
810
811
812
813
814
815
816
817
818
819void QAbstractScrollArea::setViewportMargins(
int left,
int top,
int right,
int bottom)
821 Q_D(QAbstractScrollArea);
830
831
832
833
834
835
836
837
838
839void QAbstractScrollArea::setViewportMargins(
const QMargins &margins)
841 setViewportMargins(margins.left(), margins.top(),
842 margins.right(), margins.bottom());
846
847
848
849
850
851
852QMargins QAbstractScrollArea::viewportMargins()
const
854 Q_D(
const QAbstractScrollArea);
855 return QMargins(d->left, d->top, d->right, d->bottom);
859bool QAbstractScrollArea::eventFilter(QObject *o, QEvent *e)
861 Q_D(QAbstractScrollArea);
862 if ((o == d->hbar || o == d->vbar) && (e->type() == QEvent::HoverEnter || e->type() == QEvent::HoverLeave)) {
863 if (d->hbarpolicy == Qt::ScrollBarAsNeeded && d->vbarpolicy == Qt::ScrollBarAsNeeded) {
864 QScrollBar *sbar =
static_cast<QScrollBar*>(o);
865 QScrollBar *sibling = sbar == d->hbar ? d->vbar : d->hbar;
866 if (sbar->style()->styleHint(QStyle::SH_ScrollBar_Transient,
nullptr, sbar) &&
867 sibling->style()->styleHint(QStyle::SH_ScrollBar_Transient,
nullptr, sibling))
868 d->setScrollBarTransient(sibling, e->type() == QEvent::HoverLeave);
871 return QFrame::eventFilter(o, e);
875
876
877
878
879
880
881
882
883
884
885
886bool QAbstractScrollArea::event(QEvent *e)
888 Q_D(QAbstractScrollArea);
890 case QEvent::AcceptDropsChange:
897 d->viewport->setAcceptDrops(acceptDrops());
899 case QEvent::MouseTrackingChange:
900 d->viewport->setMouseTracking(hasMouseTracking());
910 if (!d->shownOnce && d->sizeAdjustPolicy == QAbstractScrollArea::AdjustToContentsOnFirstShow) {
911 d->sizeHint = QSize();
915 return QFrame::event(e);
916 case QEvent::Paint: {
918 option.initFrom(
this);
919 if (d->cornerPaintingRect.isValid()) {
920 option.rect = d->cornerPaintingRect;
922 style()->drawPrimitive(QStyle::PE_PanelScrollAreaCorner, &option, &p,
this);
925 QFrame::paintEvent((QPaintEvent*)e);
927#ifndef QT_NO_CONTEXTMENU
928 case QEvent::ContextMenu:
929 if (
static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard)
930 return QFrame::event(e);
934 case QEvent::MouseButtonPress:
935 case QEvent::MouseButtonRelease:
936 case QEvent::MouseButtonDblClick:
937 case QEvent::MouseMove:
939#if QT_CONFIG(draganddrop)
941 case QEvent::DragEnter:
942 case QEvent::DragMove:
943 case QEvent::DragLeave:
946 case QEvent::TouchBegin:
947 case QEvent::TouchUpdate:
948 case QEvent::TouchEnd:
950#ifndef QT_NO_GESTURES
951 case QEvent::Gesture:
953 QGestureEvent *ge =
static_cast<QGestureEvent *>(e);
954 QPanGesture *g =
static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture));
956 QScrollBar *hBar = horizontalScrollBar();
957 QScrollBar *vBar = verticalScrollBar();
958 QPointF delta = g->delta();
959 if (!delta.isNull()) {
960 if (QGuiApplication::isRightToLeft())
962 int newX = hBar->value() - delta.x();
963 int newY = vBar->value() - delta.y();
964 hBar->setValue(newX);
965 vBar->setValue(newY);
972 case QEvent::ScrollPrepare:
974 QScrollPrepareEvent *se =
static_cast<QScrollPrepareEvent *>(e);
975 if (d->canStartScrollingAt(se->startPos().toPoint())) {
976 QScrollBar *hBar = horizontalScrollBar();
977 QScrollBar *vBar = verticalScrollBar();
979 se->setViewportSize(QSizeF(viewport()->size()));
980 se->setContentPosRange(QRectF(0, 0, hBar->maximum(), vBar->maximum()));
981 se->setContentPos(QPointF(hBar->value(), vBar->value()));
989 QScrollEvent *se =
static_cast<QScrollEvent *>(e);
991 QScrollBar *hBar = horizontalScrollBar();
992 QScrollBar *vBar = verticalScrollBar();
993 hBar->setValue(se->contentPos().x());
994 vBar->setValue(se->contentPos().y());
996 QPoint delta = d->overshoot - se->overshootDistance().toPoint();
998 viewport()->move(viewport()->pos() + delta);
1000 d->overshoot = se->overshootDistance().toPoint();
1004 case QEvent::StyleChange:
1005 case QEvent::LayoutDirectionChange:
1006 case QEvent::ApplicationLayoutDirectionChange:
1007 case QEvent::LayoutRequest:
1008 d->layoutChildren();
1011 return QFrame::event(e);
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036bool QAbstractScrollArea::viewportEvent(QEvent *e)
1038 switch (e->type()) {
1039 case QEvent::Resize:
1041 case QEvent::MouseButtonPress:
1042 case QEvent::MouseButtonRelease:
1043 case QEvent::MouseButtonDblClick:
1044 case QEvent::TouchBegin:
1045 case QEvent::TouchUpdate:
1046 case QEvent::TouchEnd:
1047 case QEvent::MouseMove:
1048 case QEvent::ContextMenu:
1049#if QT_CONFIG(wheelevent)
1052#if QT_CONFIG(draganddrop)
1054 case QEvent::DragEnter:
1055 case QEvent::DragMove:
1056 case QEvent::DragLeave:
1061 if (e->type() == QEvent::Resize)
1062 QWidgetPrivate::get(viewport())->resizeViewportFramebuffer();
1064 return QFrame::event(e);
1065 case QEvent::LayoutRequest:
1066#ifndef QT_NO_GESTURES
1067 case QEvent::Gesture:
1068 case QEvent::GestureOverride:
1071 case QEvent::ScrollPrepare:
1072 case QEvent::Scroll:
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093void QAbstractScrollArea::resizeEvent(QResizeEvent *)
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107void QAbstractScrollArea::paintEvent(QPaintEvent*)
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121void QAbstractScrollArea::mousePressEvent(QMouseEvent *e)
1123 QWidget::mousePressEvent(e);
1127
1128
1129
1130
1131
1132
1133void QAbstractScrollArea::mouseReleaseEvent(QMouseEvent *e)
1139
1140
1141
1142
1143
1144
1145void QAbstractScrollArea::mouseDoubleClickEvent(QMouseEvent *e)
1151
1152
1153
1154
1155
1156
1157void QAbstractScrollArea::mouseMoveEvent(QMouseEvent *e)
1163
1164
1165
1166
1167
1168
1169#if QT_CONFIG(wheelevent)
1170void QAbstractScrollArea::wheelEvent(QWheelEvent *e)
1172 Q_D(QAbstractScrollArea);
1173 if (qAbs(e->angleDelta().x()) > qAbs(e->angleDelta().y()))
1174 QCoreApplication::sendEvent(d->hbar, e);
1176 QCoreApplication::sendEvent(d->vbar, e);
1180#ifndef QT_NO_CONTEXTMENU
1182
1183
1184
1185
1186
1187
1188void QAbstractScrollArea::contextMenuEvent(QContextMenuEvent *e)
1195
1196
1197
1198
1199void QAbstractScrollArea::keyPressEvent(QKeyEvent * e)
1201 Q_D(QAbstractScrollArea);
1203#ifndef QT_NO_SHORTCUT
1204 }
else if (e == QKeySequence::MoveToPreviousPage) {
1205 d->vbar->triggerAction(QScrollBar::SliderPageStepSub);
1206 }
else if (e == QKeySequence::MoveToNextPage) {
1207 d->vbar->triggerAction(QScrollBar::SliderPageStepAdd);
1210#ifdef QT_KEYPAD_NAVIGATION
1211 if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) {
1218 d->vbar->triggerAction(QScrollBar::SliderSingleStepSub);
1221 d->vbar->triggerAction(QScrollBar::SliderSingleStepAdd);
1224#ifdef QT_KEYPAD_NAVIGATION
1225 if (QApplicationPrivate::keypadNavigationEnabled() && hasEditFocus()
1226 && (!d->hbar->isVisible() || d->hbar->value() == d->hbar->minimum())) {
1232 d->hbar->triggerAction(
1233 layoutDirection() == Qt::LeftToRight
1234 ? QScrollBar::SliderSingleStepSub : QScrollBar::SliderSingleStepAdd);
1237#ifdef QT_KEYPAD_NAVIGATION
1238 if (QApplicationPrivate::keypadNavigationEnabled() && hasEditFocus()
1239 && (!d->hbar->isVisible() || d->hbar->value() == d->hbar->maximum())) {
1245 d->hbar->triggerAction(
1246 layoutDirection() == Qt::LeftToRight
1247 ? QScrollBar::SliderSingleStepAdd : QScrollBar::SliderSingleStepSub);
1258#if QT_CONFIG(draganddrop)
1260
1261
1262
1263
1264
1265
1266
1267void QAbstractScrollArea::dragEnterEvent(QDragEnterEvent *)
1272
1273
1274
1275
1276
1277
1278
1279void QAbstractScrollArea::dragMoveEvent(QDragMoveEvent *)
1284
1285
1286
1287
1288
1289
1290
1291void QAbstractScrollArea::dragLeaveEvent(QDragLeaveEvent *)
1296
1297
1298
1299
1300
1301
1302
1303void QAbstractScrollArea::dropEvent(QDropEvent *)
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328void QAbstractScrollArea::scrollContentsBy(
int,
int)
1330 viewport()->update();
1333bool QAbstractScrollAreaPrivate::canStartScrollingAt(
const QPoint &startPos)
const
1335 Q_Q(
const QAbstractScrollArea);
1338 if (qobject_cast<QAbstractSlider *>(q->viewport()->childAt(startPos)))
1344void QAbstractScrollAreaPrivate::flashScrollBars()
1346 QStyleOptionSlider opt;
1347 hbar->initStyleOption(&opt);
1349 bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, hbar);
1350 if ((hbarpolicy != Qt::ScrollBarAlwaysOff) && (hbarpolicy == Qt::ScrollBarAsNeeded || htransient))
1351 hbar->d_func()->flash();
1352 vbar->initStyleOption(&opt);
1353 bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, vbar);
1354 if ((vbarpolicy != Qt::ScrollBarAlwaysOff) && (vbarpolicy == Qt::ScrollBarAsNeeded || vtransient))
1355 vbar->d_func()->flash();
1358void QAbstractScrollAreaPrivate::setScrollBarTransient(QScrollBar *scrollBar,
bool transient)
1360 scrollBar->d_func()->setTransient(transient);
1363void QAbstractScrollAreaPrivate::_q_hslide(
int x)
1365 Q_Q(QAbstractScrollArea);
1366 int dx = xoffset - x;
1368 q->scrollContentsBy(dx, 0);
1372void QAbstractScrollAreaPrivate::_q_vslide(
int y)
1374 Q_Q(QAbstractScrollArea);
1375 int dy = yoffset - y;
1377 q->scrollContentsBy(0, dy);
1381void QAbstractScrollAreaPrivate::_q_showOrHideScrollBars()
1386QPoint QAbstractScrollAreaPrivate::contentsOffset()
const
1388 Q_Q(
const QAbstractScrollArea);
1390 if (vbar->isVisible())
1391 offset.setY(vbar->value());
1392 if (hbar->isVisible()) {
1393 if (q->isRightToLeft())
1394 offset.setX(hbar->maximum() - hbar->value());
1396 offset.setX(hbar->value());
1402
1403
1404
1405QSize QAbstractScrollArea::minimumSizeHint()
const
1407 Q_D(
const QAbstractScrollArea);
1408 int hsbExt = d->hbar->sizeHint().height();
1409 int vsbExt = d->vbar->sizeHint().width();
1410 int extra = 2 * d->frameWidth;
1413 if ((d->frameStyle != QFrame::NoFrame)
1414 && style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt,
this)) {
1415 extra += style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt,
this);
1417 return QSize(d->scrollBarContainers[Qt::Horizontal]->sizeHint().width() + vsbExt + extra,
1418 d->scrollBarContainers[Qt::Vertical]->sizeHint().height() + hsbExt + extra);
1422
1423
1424
1425
1426QSize QAbstractScrollArea::sizeHint()
const
1428 Q_D(
const QAbstractScrollArea);
1429 if (d->sizeAdjustPolicy == QAbstractScrollArea::AdjustIgnored)
1430 return QSize(256, 192);
1432 if (!d->sizeHint.isValid() || d->sizeAdjustPolicy == QAbstractScrollArea::AdjustToContents) {
1433 const int f = 2 * d->frameWidth;
1434 const QSize frame(f, f);
1435 const bool vbarHidden = !d->vbar->isVisibleTo(
this) || d->vbarpolicy == Qt::ScrollBarAlwaysOff;
1436 const bool hbarHidden = !d->hbar->isVisibleTo(
this) || d->hbarpolicy == Qt::ScrollBarAlwaysOff;
1437 const QSize scrollbars(vbarHidden ? 0 : d->vbar->sizeHint().width(),
1438 hbarHidden ? 0 : d->hbar->sizeHint().height());
1439 d->sizeHint = frame + scrollbars + viewportSizeHint();
1445
1446
1447
1448
1449
1450QSize QAbstractScrollArea::viewportSizeHint()
const
1452 Q_D(
const QAbstractScrollArea);
1454 const QSize sh = d->viewport->sizeHint();
1459 const int h = qMax(10, fontMetrics().height());
1460 return QSize(6 * h, 4 * h);
1464
1465
1466
1467
1468
1469
1470
1471
1473QAbstractScrollArea::SizeAdjustPolicy QAbstractScrollArea::sizeAdjustPolicy()
const
1475 Q_D(
const QAbstractScrollArea);
1476 return d->sizeAdjustPolicy;
1479void QAbstractScrollArea::setSizeAdjustPolicy(SizeAdjustPolicy policy)
1481 Q_D(QAbstractScrollArea);
1482 if (d->sizeAdjustPolicy == policy)
1485 d->sizeAdjustPolicy = policy;
1486 d->sizeHint = QSize();
1491
1492
1493
1494
1495
1496
1497
1498void QAbstractScrollArea::setupViewport(QWidget *viewport)
1505#include "moc_qabstractscrollarea.cpp"
1506#include "moc_qabstractscrollarea_p.cpp"