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);
1216 d->vbar->triggerAction(QScrollBar::SliderSingleStepSub);
1219 d->vbar->triggerAction(QScrollBar::SliderSingleStepAdd);
1222 d->hbar->triggerAction(
1223 layoutDirection() == Qt::LeftToRight
1224 ? QScrollBar::SliderSingleStepSub : QScrollBar::SliderSingleStepAdd);
1227 d->hbar->triggerAction(
1228 layoutDirection() == Qt::LeftToRight
1229 ? QScrollBar::SliderSingleStepAdd : QScrollBar::SliderSingleStepSub);
1240#if QT_CONFIG(draganddrop)
1242
1243
1244
1245
1246
1247
1248
1249void QAbstractScrollArea::dragEnterEvent(QDragEnterEvent *)
1254
1255
1256
1257
1258
1259
1260
1261void QAbstractScrollArea::dragMoveEvent(QDragMoveEvent *)
1266
1267
1268
1269
1270
1271
1272
1273void QAbstractScrollArea::dragLeaveEvent(QDragLeaveEvent *)
1278
1279
1280
1281
1282
1283
1284
1285void QAbstractScrollArea::dropEvent(QDropEvent *)
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310void QAbstractScrollArea::scrollContentsBy(
int,
int)
1312 viewport()->update();
1315bool QAbstractScrollAreaPrivate::canStartScrollingAt(
const QPoint &startPos)
const
1317 Q_Q(
const QAbstractScrollArea);
1320 if (qobject_cast<QAbstractSlider *>(q->viewport()->childAt(startPos)))
1326void QAbstractScrollAreaPrivate::flashScrollBars()
1328 QStyleOptionSlider opt;
1329 hbar->initStyleOption(&opt);
1331 bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, hbar);
1332 if ((hbarpolicy != Qt::ScrollBarAlwaysOff) && (hbarpolicy == Qt::ScrollBarAsNeeded || htransient))
1333 hbar->d_func()->flash();
1334 vbar->initStyleOption(&opt);
1335 bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, vbar);
1336 if ((vbarpolicy != Qt::ScrollBarAlwaysOff) && (vbarpolicy == Qt::ScrollBarAsNeeded || vtransient))
1337 vbar->d_func()->flash();
1340void QAbstractScrollAreaPrivate::setScrollBarTransient(QScrollBar *scrollBar,
bool transient)
1342 scrollBar->d_func()->setTransient(transient);
1345void QAbstractScrollAreaPrivate::_q_hslide(
int x)
1347 Q_Q(QAbstractScrollArea);
1348 int dx = xoffset - x;
1350 q->scrollContentsBy(dx, 0);
1354void QAbstractScrollAreaPrivate::_q_vslide(
int y)
1356 Q_Q(QAbstractScrollArea);
1357 int dy = yoffset - y;
1359 q->scrollContentsBy(0, dy);
1363void QAbstractScrollAreaPrivate::_q_showOrHideScrollBars()
1368QPoint QAbstractScrollAreaPrivate::contentsOffset()
const
1370 Q_Q(
const QAbstractScrollArea);
1372 if (vbar->isVisible())
1373 offset.setY(vbar->value());
1374 if (hbar->isVisible()) {
1375 if (q->isRightToLeft())
1376 offset.setX(hbar->maximum() - hbar->value());
1378 offset.setX(hbar->value());
1384
1385
1386
1387QSize QAbstractScrollArea::minimumSizeHint()
const
1389 Q_D(
const QAbstractScrollArea);
1390 int hsbExt = d->hbar->sizeHint().height();
1391 int vsbExt = d->vbar->sizeHint().width();
1392 int extra = 2 * d->frameWidth;
1395 if ((d->frameStyle != QFrame::NoFrame)
1396 && style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt,
this)) {
1397 extra += style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt,
this);
1399 return QSize(d->scrollBarContainers[Qt::Horizontal]->sizeHint().width() + vsbExt + extra,
1400 d->scrollBarContainers[Qt::Vertical]->sizeHint().height() + hsbExt + extra);
1404
1405
1406
1407
1408QSize QAbstractScrollArea::sizeHint()
const
1410 Q_D(
const QAbstractScrollArea);
1411 if (d->sizeAdjustPolicy == QAbstractScrollArea::AdjustIgnored)
1412 return QSize(256, 192);
1414 if (!d->sizeHint.isValid() || d->sizeAdjustPolicy == QAbstractScrollArea::AdjustToContents) {
1415 const int f = 2 * d->frameWidth;
1416 const QSize frame(f, f);
1417 const bool vbarHidden = !d->vbar->isVisibleTo(
this) || d->vbarpolicy == Qt::ScrollBarAlwaysOff;
1418 const bool hbarHidden = !d->hbar->isVisibleTo(
this) || d->hbarpolicy == Qt::ScrollBarAlwaysOff;
1419 const QSize scrollbars(vbarHidden ? 0 : d->vbar->sizeHint().width(),
1420 hbarHidden ? 0 : d->hbar->sizeHint().height());
1421 d->sizeHint = frame + scrollbars + viewportSizeHint();
1427
1428
1429
1430
1431
1432QSize QAbstractScrollArea::viewportSizeHint()
const
1434 Q_D(
const QAbstractScrollArea);
1436 const QSize sh = d->viewport->sizeHint();
1441 const int h = qMax(10, fontMetrics().height());
1442 return QSize(6 * h, 4 * h);
1446
1447
1448
1449
1450
1451
1452
1453
1455QAbstractScrollArea::SizeAdjustPolicy QAbstractScrollArea::sizeAdjustPolicy()
const
1457 Q_D(
const QAbstractScrollArea);
1458 return d->sizeAdjustPolicy;
1461void QAbstractScrollArea::setSizeAdjustPolicy(SizeAdjustPolicy policy)
1463 Q_D(QAbstractScrollArea);
1464 if (d->sizeAdjustPolicy == policy)
1467 d->sizeAdjustPolicy = policy;
1468 d->sizeHint = QSize();
1473
1474
1475
1476
1477
1478
1479
1480void QAbstractScrollArea::setupViewport(QWidget *viewport)
1485int QAbstractScrollAreaPrivate::defaultSingleStep()
const
1487 auto *platformTheme = QGuiApplicationPrivate::platformTheme();
1488 return platformTheme->themeHint(QPlatformTheme::ScrollSingleStepDistance).value<
int>();
1493#include "moc_qabstractscrollarea.cpp"
1494#include "moc_qabstractscrollarea_p.cpp"