void QAbstractScrollAreaPrivate::layoutChildren() { Q_Q(QAbstractScrollArea); bool needh = (hbarpolicy == Qt::ScrollBarAlwaysOn || (hbarpolicy == Qt::ScrollBarAsNeeded && hbar->minimum() < hbar->maximum())); bool needv = (vbarpolicy == Qt::ScrollBarAlwaysOn || (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum())); #ifdef Q_WS_MAC QWidget * const window = q->window(); // Use small scroll bars for tool windows, to match the native size grip. bool hbarIsSmall = hbar->testAttribute(Qt::WA_MacSmallSize); bool vbarIsSmall = vbar->testAttribute(Qt::WA_MacSmallSize); const Qt::WindowType windowType = window->windowType(); if (windowType == Qt::Tool) { if (!hbarIsSmall) { hbar->setAttribute(Qt::WA_MacMiniSize, false); hbar->setAttribute(Qt::WA_MacNormalSize, false); hbar->setAttribute(Qt::WA_MacSmallSize, true); } if (!vbarIsSmall) { vbar->setAttribute(Qt::WA_MacMiniSize, false); vbar->setAttribute(Qt::WA_MacNormalSize, false); vbar->setAttribute(Qt::WA_MacSmallSize, true); } } else { if (hbarIsSmall) { hbar->setAttribute(Qt::WA_MacMiniSize, false); hbar->setAttribute(Qt::WA_MacNormalSize, false); hbar->setAttribute(Qt::WA_MacSmallSize, false); } if (vbarIsSmall) { vbar->setAttribute(Qt::WA_MacMiniSize, false); vbar->setAttribute(Qt::WA_MacNormalSize, false); vbar->setAttribute(Qt::WA_MacSmallSize, false); } } #endif const int hsbExt = hbar->sizeHint().height(); const int vsbExt = vbar->sizeHint().width(); const QPoint extPoint(vsbExt, hsbExt); const QSize extSize(vsbExt, hsbExt); const QRect widgetRect = q->rect(); QStyleOption opt(0); opt.init(q); const bool hasCornerWidget = (cornerWidget != 0); // If the scroll bars are at the very right and bottom of the window we // move their positions to be aligned with the size grip. #ifdef Q_WS_MAC // Check if a native sizegrip is present. bool hasMacReverseSizeGrip = false; bool hasMacSizeGrip = false; bool nativeGripPresent = false; if (q->testAttribute(Qt::WA_WState_Created)) nativeGripPresent = qt_mac_checkForNativeSizeGrip(q); if (nativeGripPresent) { // Look for a native size grip at the visual window bottom right and at the // absolute window bottom right. In reverse mode, the native size grip does not // swich side, so we need to check if it is on the "wrong side". const QPoint scrollAreaBottomRight = q->mapTo(window, widgetRect.bottomRight() - QPoint(frameWidth, frameWidth)); const QPoint windowBottomRight = window->rect().bottomRight(); const QPoint visualWindowBottomRight = QStyle::visualPos(opt.direction, opt.rect, windowBottomRight); const QPoint offset = windowBottomRight - scrollAreaBottomRight; const QPoint visualOffset = visualWindowBottomRight - scrollAreaBottomRight; hasMacSizeGrip = (visualOffset.manhattanLength() < vsbExt); hasMacReverseSizeGrip = (hasMacSizeGrip == false && (offset.manhattanLength() < hsbExt)); } #endif QPoint cornerOffset(needv ? vsbExt : 0, needh ? hsbExt : 0); QRect controlsRect; QRect viewportRect; // In FrameOnlyAroundContents mode the frame is drawn between the controls and // the viewport, else the frame rect is equal to the widget rect. if ((frameStyle != QFrame::NoFrame) && q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt, q)) { controlsRect = widgetRect; const int extra = q->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt, q); const QPoint cornerExtra(needv ? extra : 0, needh ? extra : 0); QRect frameRect = widgetRect; frameRect.adjust(0, 0, -cornerOffset.x() - cornerExtra.x(), -cornerOffset.y() - cornerExtra.y()); q->setFrameRect(QStyle::visualRect(opt.direction, opt.rect, frameRect)); // The frame rect needs to be in logical coords, however we need to flip // the contentsRect back before passing it on to the viewportRect // since the viewportRect has its logical coords calculated later. viewportRect = QStyle::visualRect(opt.direction, opt.rect, q->contentsRect()); } else { q->setFrameRect(QStyle::visualRect(opt.direction, opt.rect, widgetRect)); controlsRect = q->contentsRect(); viewportRect = QRect(controlsRect.topLeft(), controlsRect.bottomRight() - cornerOffset); } // If we have a corner widget and are only showing one scroll bar, we need to move it // to make room for the corner widget. if (hasCornerWidget && (needv || needh)) cornerOffset = extPoint; #ifdef Q_WS_MAC // Also move the scroll bars if they are covered by the native Mac size grip. if (hasMacSizeGrip) cornerOffset = extPoint; #endif // The corner point is where the scroll bar rects, the corner widget rect and the // viewport rect meets. const QPoint cornerPoint(controlsRect.bottomRight() + QPoint(1, 1) - cornerOffset); // Some styles paints the corner if both scorllbars are showing and there is // no corner widget. Also, on the Mac we paint if there is a native // (transparent) sizegrip in the area where a corner widget would be. if ((needv && needh && hasCornerWidget == false) || ((needv || needh) #ifdef Q_WS_MAC && hasMacSizeGrip #endif ) ) { cornerPaintingRect = QStyle::visualRect(opt.direction, opt.rect, QRect(cornerPoint, extSize)); } else { cornerPaintingRect = QRect(); } #ifdef Q_WS_MAC if (hasMacReverseSizeGrip) reverseCornerPaintingRect = QRect(controlsRect.bottomRight() + QPoint(1, 1) - extPoint, extSize); else reverseCornerPaintingRect = QRect(); #endif if (needh) { QRect horizontalScrollBarRect(QPoint(controlsRect.left(), cornerPoint.y()), QPoint(cornerPoint.x() - 1, controlsRect.bottom())); #ifdef Q_WS_MAC if (hasMacReverseSizeGrip) horizontalScrollBarRect.adjust(vsbExt, 0, 0, 0); #endif scrollBarContainers[Qt::Horizontal]->setGeometry(QStyle::visualRect(opt.direction, opt.rect, horizontalScrollBarRect)); scrollBarContainers[Qt::Horizontal]->raise(); } if (needv) { const QRect verticalScrollBarRect (QPoint(cornerPoint.x(), controlsRect.top()), QPoint(controlsRect.right(), cornerPoint.y() - 1)); scrollBarContainers[Qt::Vertical]->setGeometry(QStyle::visualRect(opt.direction, opt.rect, verticalScrollBarRect)); scrollBarContainers[Qt::Vertical]->raise(); } if (cornerWidget) { const QRect cornerWidgetRect(cornerPoint, controlsRect.bottomRight()); cornerWidget->setGeometry(QStyle::visualRect(opt.direction, opt.rect, cornerWidgetRect)); } scrollBarContainers[Qt::Horizontal]->setVisible(needh); scrollBarContainers[Qt::Vertical]->setVisible(needv); if (q->isRightToLeft()) viewportRect.adjust(right, top, -left, -bottom); else viewportRect.adjust(left, top, -right, -bottom); viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last }
void QAbstractScrollAreaPrivate::layoutChildren() { Q_Q(QAbstractScrollArea); const bool needh = (hbarpolicy == Qt::ScrollBarAlwaysOn || (hbarpolicy == Qt::ScrollBarAsNeeded && hbar->minimum() < hbar->maximum())); const bool needv = (vbarpolicy == Qt::ScrollBarAlwaysOn || (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum())); const int hsbExt = hbar->sizeHint().height(); const int vsbExt = vbar->sizeHint().width(); const QPoint extPoint(vsbExt, hsbExt); const QSize extSize(vsbExt, hsbExt); const QRect widgetRect = q->rect(); QStyleOption opt(0); opt.init(q); const bool hasCornerWidget = (cornerWidget != 0); QPoint cornerOffset(needv ? vsbExt : 0, needh ? hsbExt : 0); QRect controlsRect; QRect viewportRect; // In FrameOnlyAroundContents mode the frame is drawn between the controls and // the viewport, else the frame rect is equal to the widget rect. if ((frameStyle != QFrame::NoFrame) && q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt, q)) { controlsRect = widgetRect; const int extra = q->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt, q); const QPoint cornerExtra(needv ? extra : 0, needh ? extra : 0); QRect frameRect = widgetRect; frameRect.adjust(0, 0, -cornerOffset.x() - cornerExtra.x(), -cornerOffset.y() - cornerExtra.y()); q->setFrameRect(QStyle::visualRect(opt.direction, opt.rect, frameRect)); // The frame rect needs to be in logical coords, however we need to flip // the contentsRect back before passing it on to the viewportRect // since the viewportRect has its logical coords calculated later. viewportRect = QStyle::visualRect(opt.direction, opt.rect, q->contentsRect()); } else { q->setFrameRect(QStyle::visualRect(opt.direction, opt.rect, widgetRect)); controlsRect = q->contentsRect(); viewportRect = QRect(controlsRect.topLeft(), controlsRect.bottomRight() - cornerOffset); } // If we have a corner widget and are only showing one scroll bar, we need to move it // to make room for the corner widget. if (hasCornerWidget && (needv || needh)) cornerOffset = extPoint; // The corner point is where the scroll bar rects, the corner widget rect and the // viewport rect meets. const QPoint cornerPoint(controlsRect.bottomRight() + QPoint(1, 1) - cornerOffset); // Some styles paints the corner if both scorllbars are showing and there is // no corner widget. Also, on the Mac we paint if there is a native // (transparent) sizegrip in the area where a corner widget would be. if ((needv && needh && hasCornerWidget == false) || needv || needh) { cornerPaintingRect = QStyle::visualRect(opt.direction, opt.rect, QRect(cornerPoint, extSize)); } else { cornerPaintingRect = QRect(); } if (needh) { QRect horizontalScrollBarRect(QPoint(controlsRect.left(), cornerPoint.y()), QPoint(cornerPoint.x() - 1, controlsRect.bottom())); scrollBarContainers[Qt::Horizontal]->setGeometry(QStyle::visualRect(opt.direction, opt.rect, horizontalScrollBarRect)); scrollBarContainers[Qt::Horizontal]->raise(); } if (needv) { const QRect verticalScrollBarRect (QPoint(cornerPoint.x(), controlsRect.top()), QPoint(controlsRect.right(), cornerPoint.y() - 1)); scrollBarContainers[Qt::Vertical]->setGeometry(QStyle::visualRect(opt.direction, opt.rect, verticalScrollBarRect)); scrollBarContainers[Qt::Vertical]->raise(); } if (cornerWidget) { const QRect cornerWidgetRect(cornerPoint, controlsRect.bottomRight()); cornerWidget->setGeometry(QStyle::visualRect(opt.direction, opt.rect, cornerWidgetRect)); } scrollBarContainers[Qt::Horizontal]->setVisible(needh); scrollBarContainers[Qt::Vertical]->setVisible(needv); if (q->isRightToLeft()) viewportRect.adjust(right, top, -left, -bottom); else viewportRect.adjust(left, top, -right, -bottom); viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last }