7#if QT_CONFIG(scrollarea)
10#include "qapplication.h"
12#include "qstyleoption.h"
15#include "qboxlayout.h"
18#if QT_CONFIG(itemviews)
19#include "qheaderview.h"
24#include "qabstractscrollarea_p.h"
25#include "qscrollbar_p.h"
28#include <private/qguiapplication_p.h>
29#include <qpa/qplatformtheme.h>
31#include <private/qapplication_p.h>
34# include <qt_windows.h>
39using namespace Qt::StringLiterals;
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
128
129
130
131
133QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate()
134 :hbar(
nullptr), vbar(
nullptr), vbarpolicy(Qt::ScrollBarAsNeeded), hbarpolicy(Qt::ScrollBarAsNeeded),
135 shownOnce(
false), inResize(
false), sizeAdjustPolicy(QAbstractScrollArea::AdjustIgnored),
136 viewport(
nullptr), cornerWidget(
nullptr), left(0), top(0), right(0), bottom(0),
137 xoffset(0), yoffset(0), viewportFilter(
nullptr)
141QAbstractScrollAreaPrivate::~QAbstractScrollAreaPrivate()
145QAbstractScrollAreaScrollBarContainer::QAbstractScrollAreaScrollBarContainer(Qt::Orientation orientation, QWidget *parent)
146 :QWidget(parent), scrollBar(
new QScrollBar(orientation,
this)),
147 layout(
new QBoxLayout(orientation == Qt::Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom)),
148 orientation(orientation)
151 layout->setContentsMargins(QMargins());
152 layout->setSpacing(0);
153 layout->addWidget(scrollBar);
154 layout->setSizeConstraint(QLayout::SetMaximumSize);
158
159
160void QAbstractScrollAreaScrollBarContainer::addWidget(QWidget *widget, LogicalPosition position)
162 QSizePolicy policy = widget->sizePolicy();
163 if (orientation == Qt::Vertical)
164 policy.setHorizontalPolicy(QSizePolicy::Ignored);
166 policy.setVerticalPolicy(QSizePolicy::Ignored);
167 widget->setSizePolicy(policy);
168 widget->setParent(
this);
170 const int insertIndex = (position & LogicalLeft) ? 0 : scrollBarLayoutIndex() + 1;
171 layout->insertWidget(insertIndex, widget);
175
176
177
178QWidgetList QAbstractScrollAreaScrollBarContainer::widgets(LogicalPosition position)
181 const int scrollBarIndex = scrollBarLayoutIndex();
182 if (position == LogicalLeft) {
183 list.reserve(scrollBarIndex);
184 for (
int i = 0; i < scrollBarIndex; ++i)
185 list.append(layout->itemAt(i)->widget());
186 }
else if (position == LogicalRight) {
187 const int layoutItemCount = layout->count();
188 list.reserve(layoutItemCount - (scrollBarIndex + 1));
189 for (
int i = scrollBarIndex + 1; i < layoutItemCount; ++i)
190 list.append(layout->itemAt(i)->widget());
196
197
198
199
200
201int QAbstractScrollAreaScrollBarContainer::scrollBarLayoutIndex()
const
203 const int layoutItemCount = layout->count();
204 for (
int i = 0; i < layoutItemCount; ++i) {
205 if (qobject_cast<QScrollBar *>(layout->itemAt(i)->widget()))
212
213void QAbstractScrollAreaPrivate::replaceScrollBar(QScrollBar *scrollBar,
214 Qt::Orientation orientation)
216 Q_Q(QAbstractScrollArea);
218 QAbstractScrollAreaScrollBarContainer *container = scrollBarContainers[orientation];
219 bool horizontal = (orientation == Qt::Horizontal);
220 QScrollBar *oldBar = horizontal ? hbar : vbar;
225 scrollBar->setParent(container);
226 container->scrollBar = scrollBar;
227 container->layout->removeWidget(oldBar);
228 container->layout->insertWidget(0, scrollBar);
229 scrollBar->setVisible(oldBar->isVisibleTo(container));
230 scrollBar->setInvertedAppearance(oldBar->invertedAppearance());
231 scrollBar->setInvertedControls(oldBar->invertedControls());
232 scrollBar->setRange(oldBar->minimum(), oldBar->maximum());
233 scrollBar->setOrientation(oldBar->orientation());
234 scrollBar->setPageStep(oldBar->pageStep());
235 scrollBar->setSingleStep(oldBar->singleStep());
236 scrollBar->d_func()->viewMayChangeSingleStep = oldBar->d_func()->viewMayChangeSingleStep;
237 scrollBar->setSliderDown(oldBar->isSliderDown());
238 scrollBar->setSliderPosition(oldBar->sliderPosition());
239 scrollBar->setTracking(oldBar->hasTracking());
240 scrollBar->setValue(oldBar->value());
241 scrollBar->installEventFilter(q);
242 oldBar->removeEventFilter(q);
245 QObject::connect(scrollBar, SIGNAL(valueChanged(
int)),
246 q, horizontal ? SLOT(_q_hslide(
int)) : SLOT(_q_vslide(
int)));
247 QObject::connect(scrollBar, SIGNAL(rangeChanged(
int,
int)),
248 q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);
251void QAbstractScrollAreaPrivate::init()
253 Q_Q(QAbstractScrollArea);
254 viewport =
new QWidget(q);
255 viewport->setObjectName(
"qt_scrollarea_viewport"_L1);
256 viewport->setBackgroundRole(QPalette::Base);
257 viewport->setAutoFillBackground(
true);
258 scrollBarContainers[Qt::Horizontal] =
new QAbstractScrollAreaScrollBarContainer(Qt::Horizontal, q);
259 scrollBarContainers[Qt::Horizontal]->setObjectName(
"qt_scrollarea_hcontainer"_L1);
260 hbar = scrollBarContainers[Qt::Horizontal]->scrollBar;
262 scrollBarContainers[Qt::Horizontal]->setVisible(
false);
263 hbar->installEventFilter(q);
264 QObject::connect(hbar, SIGNAL(valueChanged(
int)), q, SLOT(_q_hslide(
int)));
265 QObject::connect(hbar, SIGNAL(rangeChanged(
int,
int)), q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);
266 scrollBarContainers[Qt::Vertical] =
new QAbstractScrollAreaScrollBarContainer(Qt::Vertical, q);
267 scrollBarContainers[Qt::Vertical]->setObjectName(
"qt_scrollarea_vcontainer"_L1);
268 vbar = scrollBarContainers[Qt::Vertical]->scrollBar;
270 scrollBarContainers[Qt::Vertical]->setVisible(
false);
271 vbar->installEventFilter(q);
272 QObject::connect(vbar, SIGNAL(valueChanged(
int)), q, SLOT(_q_vslide(
int)));
273 QObject::connect(vbar, SIGNAL(rangeChanged(
int,
int)), q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);
274 viewportFilter.reset(
new QAbstractScrollAreaFilter(
this));
275 viewport->installEventFilter(viewportFilter.data());
276 viewport->setFocusProxy(q);
277 q->setFocusPolicy(Qt::StrongFocus);
278 q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
279 q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
282# ifndef QT_NO_GESTURES
283 viewport->grabGesture(Qt::PanGesture);
288void QAbstractScrollAreaPrivate::layoutChildren()
292 layoutChildren_helper(&needH, &needV);
296 layoutChildren_helper(&needH, &needV);
299void QAbstractScrollAreaPrivate::layoutChildren_helper(
bool *needHorizontalScrollbar,
bool *needVerticalScrollbar)
301 Q_Q(QAbstractScrollArea);
302 QStyleOptionSlider barOpt;
304 hbar->initStyleOption(&barOpt);
305 bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &barOpt, hbar);
306 bool needh = *needHorizontalScrollbar || ((hbarpolicy != Qt::ScrollBarAlwaysOff) && ((hbarpolicy == Qt::ScrollBarAlwaysOn && !htransient)
307 || ((hbarpolicy == Qt::ScrollBarAsNeeded || htransient)
308 && hbar->minimum() < hbar->maximum() && !hbar->sizeHint().isEmpty())));
309 const int hscrollOverlap = hbar->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarOverlap, &barOpt, hbar);
311 vbar->initStyleOption(&barOpt);
312 bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &barOpt, vbar);
313 bool needv = *needVerticalScrollbar || ((vbarpolicy != Qt::ScrollBarAlwaysOff) && ((vbarpolicy == Qt::ScrollBarAlwaysOn && !vtransient)
314 || ((vbarpolicy == Qt::ScrollBarAsNeeded || vtransient)
315 && vbar->minimum() < vbar->maximum() && !vbar->sizeHint().isEmpty())));
316 const int vscrollOverlap = vbar->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarOverlap, &barOpt, vbar);
321 const int hsbExt = hbar->sizeHint().height();
322 const int vsbExt = vbar->sizeHint().width();
323 const QPoint extPoint(vsbExt, hsbExt);
324 const QSize extSize(vsbExt, hsbExt);
326 const QRect widgetRect = q->rect();
328 const bool hasCornerWidget = (cornerWidget !=
nullptr);
330 QPoint cornerOffset((needv && vscrollOverlap == 0) ? vsbExt : 0, (needh && hscrollOverlap == 0) ? hsbExt : 0);
336 if ((frameStyle != QFrame::NoFrame) &&
337 q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt, q)) {
338 controlsRect = widgetRect;
339 const int spacing = q->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt, q);
340 const QPoint cornerExtra(needv ? spacing + vscrollOverlap : 0, needh ? spacing + hscrollOverlap : 0);
341 QRect frameRect = widgetRect;
342 frameRect.adjust(0, 0, -cornerOffset.x() - cornerExtra.x(), -cornerOffset.y() - cornerExtra.y());
343 q->setFrameRect(QStyle::visualRect(opt.direction, opt.rect, frameRect));
347 viewportRect = QStyle::visualRect(opt.direction, opt.rect, q->contentsRect());
349 q->setFrameRect(QStyle::visualRect(opt.direction, opt.rect, widgetRect));
350 controlsRect = q->contentsRect();
351 viewportRect = QRect(controlsRect.topLeft(), controlsRect.bottomRight() - cornerOffset);
354 cornerOffset = QPoint(needv ? vsbExt : 0, needh ? hsbExt : 0);
358 if (hasCornerWidget && ((needv && vscrollOverlap == 0) || (needh && hscrollOverlap == 0)))
359 cornerOffset = extPoint;
363 const QPoint cornerPoint(controlsRect.bottomRight() + QPoint(1, 1) - cornerOffset);
367 if (needv && needh && !hasCornerWidget && hscrollOverlap == 0 && vscrollOverlap == 0)
368 cornerPaintingRect = QStyle::visualRect(opt.direction, opt.rect, QRect(cornerPoint, extSize));
370 cornerPaintingRect = QRect();
373 int vHeaderRight = 0;
374 int hHeaderBottom = 0;
375#if QT_CONFIG(itemviews)
376 if ((vscrollOverlap > 0 && needv) || (hscrollOverlap > 0 && needh)) {
377 const QList<QHeaderView *> headers = q->findChildren<QHeaderView*>();
378 if (headers.size() <= 2) {
379 for (
const QHeaderView *header : headers) {
380 const QRect geo = header->geometry();
381 if (header->orientation() == Qt::Vertical && header->isVisible() && QStyle::visualRect(opt.direction, opt.rect, geo).left() <= opt.rect.width() / 2)
382 vHeaderRight = QStyle::visualRect(opt.direction, opt.rect, geo).right();
383 else if (header->orientation() == Qt::Horizontal && header->isVisible() && geo.top() <= q->frameWidth())
384 hHeaderBottom = geo.bottom();
390 QRect horizontalScrollBarRect(QPoint(controlsRect.left() + vHeaderRight, cornerPoint.y()), QPoint(cornerPoint.x() - 1, controlsRect.bottom()));
392 if (!hasCornerWidget && htransient)
393 horizontalScrollBarRect.adjust(0, 0, cornerOffset.x(), 0);
394 scrollBarContainers[Qt::Horizontal]->setGeometry(QStyle::visualRect(opt.direction, opt.rect, horizontalScrollBarRect));
395 scrollBarContainers[Qt::Horizontal]->raise();
399 QRect verticalScrollBarRect (QPoint(cornerPoint.x(), controlsRect.top() + hHeaderBottom), QPoint(controlsRect.right(), cornerPoint.y() - 1));
400 if (!hasCornerWidget && vtransient)
401 verticalScrollBarRect.adjust(0, 0, 0, cornerOffset.y());
402 scrollBarContainers[Qt::Vertical]->setGeometry(QStyle::visualRect(opt.direction, opt.rect, verticalScrollBarRect));
403 scrollBarContainers[Qt::Vertical]->raise();
407 const QRect cornerWidgetRect(cornerPoint, controlsRect.bottomRight());
408 cornerWidget->setGeometry(QStyle::visualRect(opt.direction, opt.rect, cornerWidgetRect));
411 scrollBarContainers[Qt::Horizontal]->setVisible(needh);
412 scrollBarContainers[Qt::Vertical]->setVisible(needv);
414 if (q->isRightToLeft())
415 viewportRect.adjust(right, top, -left, -bottom);
417 viewportRect.adjust(left, top, -right, -bottom);
418 viewportRect = QStyle::visualRect(opt.direction, opt.rect, viewportRect);
419 viewportRect.translate(-overshoot);
420 viewport->setGeometry(viewportRect);
422 *needHorizontalScrollbar = needh;
423 *needVerticalScrollbar = needv;
427
428
429
430
431
432
433
434
435
436
440
441
442
443
444QAbstractScrollArea::QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget *parent)
447 Q_D(QAbstractScrollArea);
451 d->viewportFilter.reset();
457
458
459
460
461QAbstractScrollArea::QAbstractScrollArea(QWidget *parent)
462 :QFrame(*
new QAbstractScrollAreaPrivate, parent)
464 Q_D(QAbstractScrollArea);
468 d->viewportFilter.reset();
475
476
477QAbstractScrollArea::~QAbstractScrollArea()
479 Q_D(QAbstractScrollArea);
481 d->viewportFilter.reset();
486
487
488
489
490
491
492
493
494
495void QAbstractScrollArea::setViewport(QWidget *widget)
497 Q_D(QAbstractScrollArea);
498 if (widget != d->viewport) {
499 QWidget *oldViewport = d->viewport;
501 widget =
new QWidget;
502 d->viewport = widget;
503 d->viewport->setParent(
this);
504 d->viewport->setFocusProxy(
this);
505 d->viewport->installEventFilter(d->viewportFilter.data());
506#ifndef QT_NO_GESTURES
507 d->viewport->grabGesture(Qt::PanGesture);
511 QWidgetPrivate::get(d->viewport)->initializeViewportFramebuffer();
515 setupViewport(widget);
521
522
523
524
525
526
527
528QWidget *QAbstractScrollArea::viewport()
const
530 Q_D(
const QAbstractScrollArea);
536
537
538
539QSize QAbstractScrollArea::maximumViewportSize()
const
541 Q_D(
const QAbstractScrollArea);
542 int f = 2 * d->frameWidth;
543 QSize max = size() - QSize(f + d->left + d->right, f + d->top + d->bottom);
545 if (d->vbarpolicy == Qt::ScrollBarAlwaysOn)
546 max.rwidth() -= d->vbar->sizeHint().width();
547 if (d->hbarpolicy == Qt::ScrollBarAlwaysOn)
548 max.rheight() -= d->hbar->sizeHint().height();
553
554
555
556
557
558
559
561Qt::ScrollBarPolicy QAbstractScrollArea::verticalScrollBarPolicy()
const
563 Q_D(
const QAbstractScrollArea);
564 return d->vbarpolicy;
567void QAbstractScrollArea::setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy)
569 Q_D(QAbstractScrollArea);
570 const Qt::ScrollBarPolicy oldPolicy = d->vbarpolicy;
571 d->vbarpolicy = policy;
574 if (oldPolicy != d->vbarpolicy)
575 d->scrollBarPolicyChanged(Qt::Vertical, d->vbarpolicy);
580
581
582
583
584QScrollBar *QAbstractScrollArea::verticalScrollBar()
const
586 Q_D(
const QAbstractScrollArea);
591
592
593
594
595
596
597
598
599
600
601
602void QAbstractScrollArea::setVerticalScrollBar(QScrollBar *scrollBar)
604 Q_D(QAbstractScrollArea);
605 if (Q_UNLIKELY(!scrollBar)) {
606 qWarning(
"QAbstractScrollArea::setVerticalScrollBar: Cannot set a null scroll bar");
610 d->replaceScrollBar(scrollBar, Qt::Vertical);
614
615
616
617
618
619
620
622Qt::ScrollBarPolicy QAbstractScrollArea::horizontalScrollBarPolicy()
const
624 Q_D(
const QAbstractScrollArea);
625 return d->hbarpolicy;
628void QAbstractScrollArea::setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy)
630 Q_D(QAbstractScrollArea);
631 const Qt::ScrollBarPolicy oldPolicy = d->hbarpolicy;
632 d->hbarpolicy = policy;
635 if (oldPolicy != d->hbarpolicy)
636 d->scrollBarPolicyChanged(Qt::Horizontal, d->hbarpolicy);
640
641
642
643
644QScrollBar *QAbstractScrollArea::horizontalScrollBar()
const
646 Q_D(
const QAbstractScrollArea);
651
652
653
654
655
656
657
658
659
660
661
662
663void QAbstractScrollArea::setHorizontalScrollBar(QScrollBar *scrollBar)
665 Q_D(QAbstractScrollArea);
666 if (Q_UNLIKELY(!scrollBar)) {
667 qWarning(
"QAbstractScrollArea::setHorizontalScrollBar: Cannot set a null scroll bar");
671 d->replaceScrollBar(scrollBar, Qt::Horizontal);
675
676
677
678
679
680
681QWidget *QAbstractScrollArea::cornerWidget()
const
683 Q_D(
const QAbstractScrollArea);
684 return d->cornerWidget;
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713void QAbstractScrollArea::setCornerWidget(QWidget *widget)
715 Q_D(QAbstractScrollArea);
716 QWidget* oldWidget = d->cornerWidget;
717 if (oldWidget != widget) {
720 d->cornerWidget = widget;
722 if (widget && widget->parentWidget() !=
this)
723 widget->setParent(
this);
729 d->cornerWidget = widget;
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
762
763
764
765
766void QAbstractScrollArea::addScrollBarWidget(QWidget *widget, Qt::Alignment alignment)
768 Q_D(QAbstractScrollArea);
770 if (widget ==
nullptr)
773 const Qt::Orientation scrollBarOrientation
774 = ((alignment & Qt::AlignLeft) || (alignment & Qt::AlignRight)) ? Qt::Horizontal : Qt::Vertical;
775 const QAbstractScrollAreaScrollBarContainer::LogicalPosition position
776 = ((alignment & Qt::AlignRight) || (alignment & Qt::AlignBottom))
777 ? QAbstractScrollAreaScrollBarContainer::LogicalRight : QAbstractScrollAreaScrollBarContainer::LogicalLeft;
778 d->scrollBarContainers[scrollBarOrientation]->addWidget(widget, position);
780 if (isHidden() ==
false)
785
786
787
788
789
790
791QWidgetList QAbstractScrollArea::scrollBarWidgets(Qt::Alignment alignment)
793 Q_D(QAbstractScrollArea);
797 if (alignment & Qt::AlignLeft)
798 list += d->scrollBarContainers[Qt::Horizontal]->widgets(QAbstractScrollAreaScrollBarContainer::LogicalLeft);
799 if (alignment & Qt::AlignRight)
800 list += d->scrollBarContainers[Qt::Horizontal]->widgets(QAbstractScrollAreaScrollBarContainer::LogicalRight);
801 if (alignment & Qt::AlignTop)
802 list += d->scrollBarContainers[Qt::Vertical]->widgets(QAbstractScrollAreaScrollBarContainer::LogicalLeft);
803 if (alignment & Qt::AlignBottom)
804 list += d->scrollBarContainers[Qt::Vertical]->widgets(QAbstractScrollAreaScrollBarContainer::LogicalRight);
810
811
812
813
814
815
816
817
818
819
820
821
822
823void QAbstractScrollArea::setViewportMargins(
int left,
int top,
int right,
int bottom)
825 Q_D(QAbstractScrollArea);
834
835
836
837
838
839
840
841
842
843void QAbstractScrollArea::setViewportMargins(
const QMargins &margins)
845 setViewportMargins(margins.left(), margins.top(),
846 margins.right(), margins.bottom());
850
851
852
853
854
855
856QMargins QAbstractScrollArea::viewportMargins()
const
858 Q_D(
const QAbstractScrollArea);
859 return QMargins(d->left, d->top, d->right, d->bottom);
863bool QAbstractScrollArea::eventFilter(QObject *o, QEvent *e)
865 Q_D(QAbstractScrollArea);
866 if ((o == d->hbar || o == d->vbar) && (e->type() == QEvent::HoverEnter || e->type() == QEvent::HoverLeave)) {
867 if (d->hbarpolicy == Qt::ScrollBarAsNeeded && d->vbarpolicy == Qt::ScrollBarAsNeeded) {
868 QScrollBar *sbar =
static_cast<QScrollBar*>(o);
869 QScrollBar *sibling = sbar == d->hbar ? d->vbar : d->hbar;
870 if (sbar->style()->styleHint(QStyle::SH_ScrollBar_Transient,
nullptr, sbar) &&
871 sibling->style()->styleHint(QStyle::SH_ScrollBar_Transient,
nullptr, sibling))
872 d->setScrollBarTransient(sibling, e->type() == QEvent::HoverLeave);
875 return QFrame::eventFilter(o, e);
879
880
881
882
883
884
885
886
887
888
889
890bool QAbstractScrollArea::event(QEvent *e)
892 Q_D(QAbstractScrollArea);
894 case QEvent::AcceptDropsChange:
901 d->viewport->setAcceptDrops(acceptDrops());
903 case QEvent::MouseTrackingChange:
904 d->viewport->setMouseTracking(hasMouseTracking());
914 if (!d->shownOnce && d->sizeAdjustPolicy == QAbstractScrollArea::AdjustToContentsOnFirstShow) {
915 d->sizeHint = QSize();
919 return QFrame::event(e);
920 case QEvent::Paint: {
922 option.initFrom(
this);
923 if (d->cornerPaintingRect.isValid()) {
924 option.rect = d->cornerPaintingRect;
926 style()->drawPrimitive(QStyle::PE_PanelScrollAreaCorner, &option, &p,
this);
929 QFrame::paintEvent((QPaintEvent*)e);
931#ifndef QT_NO_CONTEXTMENU
932 case QEvent::ContextMenu:
933 if (
static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard)
934 return QFrame::event(e);
938 case QEvent::MouseButtonPress:
939 case QEvent::MouseButtonRelease:
940 case QEvent::MouseButtonDblClick:
941 case QEvent::MouseMove:
943#if QT_CONFIG(draganddrop)
945 case QEvent::DragEnter:
946 case QEvent::DragMove:
947 case QEvent::DragLeave:
950 case QEvent::TouchBegin:
951 case QEvent::TouchUpdate:
952 case QEvent::TouchEnd:
954#ifndef QT_NO_GESTURES
955 case QEvent::Gesture:
957 QGestureEvent *ge =
static_cast<QGestureEvent *>(e);
958 QPanGesture *g =
static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture));
960 QScrollBar *hBar = horizontalScrollBar();
961 QScrollBar *vBar = verticalScrollBar();
962 QPointF delta = g->delta();
963 if (!delta.isNull()) {
964 if (QGuiApplication::isRightToLeft())
966 int newX = hBar->value() - delta.x();
967 int newY = vBar->value() - delta.y();
968 hBar->setValue(newX);
969 vBar->setValue(newY);
976 case QEvent::ScrollPrepare:
978 QScrollPrepareEvent *se =
static_cast<QScrollPrepareEvent *>(e);
979 if (d->canStartScrollingAt(se->startPos().toPoint())) {
980 QScrollBar *hBar = horizontalScrollBar();
981 QScrollBar *vBar = verticalScrollBar();
983 se->setViewportSize(QSizeF(viewport()->size()));
984 se->setContentPosRange(QRectF(0, 0, hBar->maximum(), vBar->maximum()));
985 se->setContentPos(QPointF(hBar->value(), vBar->value()));
993 QScrollEvent *se =
static_cast<QScrollEvent *>(e);
995 QScrollBar *hBar = horizontalScrollBar();
996 QScrollBar *vBar = verticalScrollBar();
997 hBar->setValue(se->contentPos().x());
998 vBar->setValue(se->contentPos().y());
1000 QPoint delta = d->overshoot - se->overshootDistance().toPoint();
1001 if (!delta.isNull())
1002 viewport()->move(viewport()->pos() + delta);
1004 d->overshoot = se->overshootDistance().toPoint();
1008 case QEvent::StyleChange:
1009 case QEvent::LayoutDirectionChange:
1010 case QEvent::ApplicationLayoutDirectionChange:
1011 case QEvent::LayoutRequest:
1012 d->layoutChildren();
1015 return QFrame::event(e);
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040bool QAbstractScrollArea::viewportEvent(QEvent *e)
1042 switch (e->type()) {
1043 case QEvent::Resize:
1045 case QEvent::MouseButtonPress:
1046 case QEvent::MouseButtonRelease:
1047 case QEvent::MouseButtonDblClick:
1048 case QEvent::TouchBegin:
1049 case QEvent::TouchUpdate:
1050 case QEvent::TouchEnd:
1051 case QEvent::MouseMove:
1052 case QEvent::ContextMenu:
1053#if QT_CONFIG(wheelevent)
1056#if QT_CONFIG(draganddrop)
1058 case QEvent::DragEnter:
1059 case QEvent::DragMove:
1060 case QEvent::DragLeave:
1065 if (e->type() == QEvent::Resize)
1066 QWidgetPrivate::get(viewport())->resizeViewportFramebuffer();
1068 return QFrame::event(e);
1069 case QEvent::LayoutRequest:
1070#ifndef QT_NO_GESTURES
1071 case QEvent::Gesture:
1072 case QEvent::GestureOverride:
1075 case QEvent::ScrollPrepare:
1076 case QEvent::Scroll:
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097void QAbstractScrollArea::resizeEvent(QResizeEvent *)
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111void QAbstractScrollArea::paintEvent(QPaintEvent*)
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125void QAbstractScrollArea::mousePressEvent(QMouseEvent *e)
1127 QWidget::mousePressEvent(e);
1131
1132
1133
1134
1135
1136
1137void QAbstractScrollArea::mouseReleaseEvent(QMouseEvent *e)
1143
1144
1145
1146
1147
1148
1149void QAbstractScrollArea::mouseDoubleClickEvent(QMouseEvent *e)
1155
1156
1157
1158
1159
1160
1161void QAbstractScrollArea::mouseMoveEvent(QMouseEvent *e)
1167
1168
1169
1170
1171
1172
1173#if QT_CONFIG(wheelevent)
1174void QAbstractScrollArea::wheelEvent(QWheelEvent *e)
1176 Q_D(QAbstractScrollArea);
1177 if (qAbs(e->angleDelta().x()) > qAbs(e->angleDelta().y()))
1178 QCoreApplication::sendEvent(d->hbar, e);
1180 QCoreApplication::sendEvent(d->vbar, e);
1184#ifndef QT_NO_CONTEXTMENU
1186
1187
1188
1189
1190
1191
1192void QAbstractScrollArea::contextMenuEvent(QContextMenuEvent *e)
1199
1200
1201
1202
1203void QAbstractScrollArea::keyPressEvent(QKeyEvent * e)
1205 Q_D(QAbstractScrollArea);
1207#ifndef QT_NO_SHORTCUT
1208 }
else if (e == QKeySequence::MoveToPreviousPage) {
1209 d->vbar->triggerAction(QScrollBar::SliderPageStepSub);
1210 }
else if (e == QKeySequence::MoveToNextPage) {
1211 d->vbar->triggerAction(QScrollBar::SliderPageStepAdd);
1214#ifdef QT_KEYPAD_NAVIGATION
1215 if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) {
1222 d->vbar->triggerAction(QScrollBar::SliderSingleStepSub);
1225 d->vbar->triggerAction(QScrollBar::SliderSingleStepAdd);
1228#ifdef QT_KEYPAD_NAVIGATION
1229 if (QApplicationPrivate::keypadNavigationEnabled() && hasEditFocus()
1230 && (!d->hbar->isVisible() || d->hbar->value() == d->hbar->minimum())) {
1236 d->hbar->triggerAction(
1237 layoutDirection() == Qt::LeftToRight
1238 ? QScrollBar::SliderSingleStepSub : QScrollBar::SliderSingleStepAdd);
1241#ifdef QT_KEYPAD_NAVIGATION
1242 if (QApplicationPrivate::keypadNavigationEnabled() && hasEditFocus()
1243 && (!d->hbar->isVisible() || d->hbar->value() == d->hbar->maximum())) {
1249 d->hbar->triggerAction(
1250 layoutDirection() == Qt::LeftToRight
1251 ? QScrollBar::SliderSingleStepAdd : QScrollBar::SliderSingleStepSub);
1262#if QT_CONFIG(draganddrop)
1264
1265
1266
1267
1268
1269
1270
1271void QAbstractScrollArea::dragEnterEvent(QDragEnterEvent *)
1276
1277
1278
1279
1280
1281
1282
1283void QAbstractScrollArea::dragMoveEvent(QDragMoveEvent *)
1288
1289
1290
1291
1292
1293
1294
1295void QAbstractScrollArea::dragLeaveEvent(QDragLeaveEvent *)
1300
1301
1302
1303
1304
1305
1306
1307void QAbstractScrollArea::dropEvent(QDropEvent *)
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332void QAbstractScrollArea::scrollContentsBy(
int,
int)
1334 viewport()->update();
1337bool QAbstractScrollAreaPrivate::canStartScrollingAt(
const QPoint &startPos)
const
1339 Q_Q(
const QAbstractScrollArea);
1342 if (qobject_cast<QAbstractSlider *>(q->viewport()->childAt(startPos)))
1348void QAbstractScrollAreaPrivate::flashScrollBars()
1350 QStyleOptionSlider opt;
1351 hbar->initStyleOption(&opt);
1353 bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, hbar);
1354 if ((hbarpolicy != Qt::ScrollBarAlwaysOff) && (hbarpolicy == Qt::ScrollBarAsNeeded || htransient))
1355 hbar->d_func()->flash();
1356 vbar->initStyleOption(&opt);
1357 bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, vbar);
1358 if ((vbarpolicy != Qt::ScrollBarAlwaysOff) && (vbarpolicy == Qt::ScrollBarAsNeeded || vtransient))
1359 vbar->d_func()->flash();
1362void QAbstractScrollAreaPrivate::setScrollBarTransient(QScrollBar *scrollBar,
bool transient)
1364 scrollBar->d_func()->setTransient(transient);
1367void QAbstractScrollAreaPrivate::_q_hslide(
int x)
1369 Q_Q(QAbstractScrollArea);
1370 int dx = xoffset - x;
1372 q->scrollContentsBy(dx, 0);
1376void QAbstractScrollAreaPrivate::_q_vslide(
int y)
1378 Q_Q(QAbstractScrollArea);
1379 int dy = yoffset - y;
1381 q->scrollContentsBy(0, dy);
1385void QAbstractScrollAreaPrivate::_q_showOrHideScrollBars()
1390QPoint QAbstractScrollAreaPrivate::contentsOffset()
const
1392 Q_Q(
const QAbstractScrollArea);
1394 if (vbar->isVisible())
1395 offset.setY(vbar->value());
1396 if (hbar->isVisible()) {
1397 if (q->isRightToLeft())
1398 offset.setX(hbar->maximum() - hbar->value());
1400 offset.setX(hbar->value());
1406
1407
1408
1409QSize QAbstractScrollArea::minimumSizeHint()
const
1411 Q_D(
const QAbstractScrollArea);
1412 int hsbExt = d->hbar->sizeHint().height();
1413 int vsbExt = d->vbar->sizeHint().width();
1414 int extra = 2 * d->frameWidth;
1417 if ((d->frameStyle != QFrame::NoFrame)
1418 && style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt,
this)) {
1419 extra += style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt,
this);
1421 return QSize(d->scrollBarContainers[Qt::Horizontal]->sizeHint().width() + vsbExt + extra,
1422 d->scrollBarContainers[Qt::Vertical]->sizeHint().height() + hsbExt + extra);
1426
1427
1428
1429
1430QSize QAbstractScrollArea::sizeHint()
const
1432 Q_D(
const QAbstractScrollArea);
1433 if (d->sizeAdjustPolicy == QAbstractScrollArea::AdjustIgnored)
1434 return QSize(256, 192);
1436 if (!d->sizeHint.isValid() || d->sizeAdjustPolicy == QAbstractScrollArea::AdjustToContents) {
1437 const int f = 2 * d->frameWidth;
1438 const QSize frame(f, f);
1439 const bool vbarHidden = !d->vbar->isVisibleTo(
this) || d->vbarpolicy == Qt::ScrollBarAlwaysOff;
1440 const bool hbarHidden = !d->hbar->isVisibleTo(
this) || d->hbarpolicy == Qt::ScrollBarAlwaysOff;
1441 const QSize scrollbars(vbarHidden ? 0 : d->vbar->sizeHint().width(),
1442 hbarHidden ? 0 : d->hbar->sizeHint().height());
1443 d->sizeHint = frame + scrollbars + viewportSizeHint();
1449
1450
1451
1452
1453
1454QSize QAbstractScrollArea::viewportSizeHint()
const
1456 Q_D(
const QAbstractScrollArea);
1458 const QSize sh = d->viewport->sizeHint();
1463 const int h = qMax(10, fontMetrics().height());
1464 return QSize(6 * h, 4 * h);
1468
1469
1470
1471
1472
1473
1474
1475
1477QAbstractScrollArea::SizeAdjustPolicy QAbstractScrollArea::sizeAdjustPolicy()
const
1479 Q_D(
const QAbstractScrollArea);
1480 return d->sizeAdjustPolicy;
1483void QAbstractScrollArea::setSizeAdjustPolicy(SizeAdjustPolicy policy)
1485 Q_D(QAbstractScrollArea);
1486 if (d->sizeAdjustPolicy == policy)
1489 d->sizeAdjustPolicy = policy;
1490 d->sizeHint = QSize();
1495
1496
1497
1498
1499
1500
1501
1502void QAbstractScrollArea::setupViewport(QWidget *viewport)
1507int QAbstractScrollAreaPrivate::defaultSingleStep()
const
1509 auto *platformTheme = QGuiApplicationPrivate::platformTheme();
1510 return platformTheme->themeHint(QPlatformTheme::ScrollSingleStepDistance).value<
int>();
1515#include "moc_qabstractscrollarea.cpp"
1516#include "moc_qabstractscrollarea_p.cpp"