📄 renderlayer.cpp
字号:
scrollbar = 0; }}void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar){ if (hasScrollbar == (m_hBar != 0)) return; if (hasScrollbar) m_hBar = createScrollbar(HorizontalScrollbar); else destroyScrollbar(HorizontalScrollbar); // Destroying or creating one bar can cause our scrollbar corner to come and go. We need to update the opposite scrollbar's style. if (m_hBar) m_hBar->styleChanged(); if (m_vBar) m_vBar->styleChanged();#if ENABLE(DASHBOARD_SUPPORT) // Force an update since we know the scrollbars have changed things. if (renderer()->document()->hasDashboardRegions()) renderer()->document()->setDashboardRegionsDirty(true);#endif}void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar){ if (hasScrollbar == (m_vBar != 0)) return; if (hasScrollbar) m_vBar = createScrollbar(VerticalScrollbar); else destroyScrollbar(VerticalScrollbar); // Destroying or creating one bar can cause our scrollbar corner to come and go. We need to update the opposite scrollbar's style. if (m_hBar) m_hBar->styleChanged(); if (m_vBar) m_vBar->styleChanged();#if ENABLE(DASHBOARD_SUPPORT) // Force an update since we know the scrollbars have changed things. if (renderer()->document()->hasDashboardRegions()) renderer()->document()->setDashboardRegionsDirty(true);#endif}int RenderLayer::verticalScrollbarWidth() const{ if (!m_vBar) return 0; return m_vBar->width();}int RenderLayer::horizontalScrollbarHeight() const{ if (!m_hBar) return 0; return m_hBar->height();}IntSize RenderLayer::offsetFromResizeCorner(const IntPoint& absolutePoint) const{ // Currently the resize corner is always the bottom right corner IntPoint bottomRight(width(), height()); IntPoint localPoint = absoluteToContents(absolutePoint); return localPoint - bottomRight;}void RenderLayer::positionOverflowControls(int tx, int ty){ if (!m_hBar && !m_vBar && (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE)) return; RenderBox* box = renderBox(); if (!box) return; IntRect borderBox = box->borderBoxRect(); IntRect scrollCorner(scrollCornerRect(this, borderBox)); IntRect absBounds(borderBox.x() + tx, borderBox.y() + ty, borderBox.width(), borderBox.height()); if (m_vBar) m_vBar->setFrameRect(IntRect(absBounds.right() - box->borderRight() - m_vBar->width(), absBounds.y() + box->borderTop(), m_vBar->width(), absBounds.height() - (box->borderTop() + box->borderBottom()) - scrollCorner.height())); if (m_hBar) m_hBar->setFrameRect(IntRect(absBounds.x() + box->borderLeft(), absBounds.bottom() - box->borderBottom() - m_hBar->height(), absBounds.width() - (box->borderLeft() + box->borderRight()) - scrollCorner.width(), m_hBar->height())); if (m_scrollCorner) m_scrollCorner->setFrameRect(scrollCorner); if (m_resizer) m_resizer->setFrameRect(resizerCornerRect(this, borderBox));}int RenderLayer::scrollWidth(){ if (m_scrollDimensionsDirty) computeScrollDimensions(); return m_scrollWidth;}int RenderLayer::scrollHeight(){ if (m_scrollDimensionsDirty) computeScrollDimensions(); return m_scrollHeight;}void RenderLayer::computeScrollDimensions(bool* needHBar, bool* needVBar){ RenderBox* box = renderBox(); ASSERT(box); m_scrollDimensionsDirty = false; bool ltr = renderer()->style()->direction() == LTR; int clientWidth = box->clientWidth(); int clientHeight = box->clientHeight(); m_scrollLeftOverflow = ltr ? 0 : min(0, box->leftmostPosition(true, false) - box->borderLeft()); int rightPos = ltr ? box->rightmostPosition(true, false) - box->borderLeft() : clientWidth - m_scrollLeftOverflow; int bottomPos = box->lowestPosition(true, false) - box->borderTop(); m_scrollWidth = max(rightPos, clientWidth); m_scrollHeight = max(bottomPos, clientHeight); m_scrollOriginX = ltr ? 0 : m_scrollWidth - clientWidth; if (needHBar) *needHBar = rightPos > clientWidth; if (needVBar) *needVBar = bottomPos > clientHeight;}void RenderLayer::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow){ if (m_overflowStatusDirty) { m_horizontalOverflow = horizontalOverflow; m_verticalOverflow = verticalOverflow; m_overflowStatusDirty = false; return; } bool horizontalOverflowChanged = (m_horizontalOverflow != horizontalOverflow); bool verticalOverflowChanged = (m_verticalOverflow != verticalOverflow); if (horizontalOverflowChanged || verticalOverflowChanged) { m_horizontalOverflow = horizontalOverflow; m_verticalOverflow = verticalOverflow; if (FrameView* frameView = renderer()->document()->view()) { frameView->scheduleEvent(OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow, verticalOverflowChanged, verticalOverflow), renderer()->node()); } }}voidRenderLayer::updateScrollInfoAfterLayout(){ RenderBox* box = renderBox(); if (!box) return; m_scrollDimensionsDirty = true; bool horizontalOverflow, verticalOverflow; computeScrollDimensions(&horizontalOverflow, &verticalOverflow); if (box->style()->overflowX() != OMARQUEE) { // Layout may cause us to be in an invalid scroll position. In this case we need // to pull our scroll offsets back to the max (or push them up to the min). int newX = max(0, min(scrollXOffset(), scrollWidth() - box->clientWidth())); int newY = max(0, min(m_scrollY, scrollHeight() - box->clientHeight())); if (newX != scrollXOffset() || newY != m_scrollY) { RenderView* view = renderer()->view(); ASSERT(view); // scrollToOffset() may call updateLayerPositions(), which doesn't work // with LayoutState. // FIXME: Remove the disableLayoutState/enableLayoutState if the above changes. if (view) view->disableLayoutState(); scrollToOffset(newX, newY); if (view) view->enableLayoutState(); } } bool haveHorizontalBar = m_hBar; bool haveVerticalBar = m_vBar; // overflow:scroll should just enable/disable. if (renderer()->style()->overflowX() == OSCROLL) m_hBar->setEnabled(horizontalOverflow); if (renderer()->style()->overflowY() == OSCROLL) m_vBar->setEnabled(verticalOverflow); // A dynamic change from a scrolling overflow to overflow:hidden means we need to get rid of any // scrollbars that may be present. if (renderer()->style()->overflowX() == OHIDDEN && haveHorizontalBar) setHasHorizontalScrollbar(false); if (renderer()->style()->overflowY() == OHIDDEN && haveVerticalBar) setHasVerticalScrollbar(false); // overflow:auto may need to lay out again if scrollbars got added/removed. bool scrollbarsChanged = (box->hasAutoHorizontalScrollbar() && haveHorizontalBar != horizontalOverflow) || (box->hasAutoVerticalScrollbar() && haveVerticalBar != verticalOverflow); if (scrollbarsChanged) { if (box->hasAutoHorizontalScrollbar()) setHasHorizontalScrollbar(horizontalOverflow); if (box->hasAutoVerticalScrollbar()) setHasVerticalScrollbar(verticalOverflow);#if ENABLE(DASHBOARD_SUPPORT) // Force an update since we know the scrollbars have changed things. if (renderer()->document()->hasDashboardRegions()) renderer()->document()->setDashboardRegionsDirty(true);#endif renderer()->repaint(); if (renderer()->style()->overflowX() == OAUTO || renderer()->style()->overflowY() == OAUTO) { if (!m_inOverflowRelayout) { // Our proprietary overflow: overlay value doesn't trigger a layout. m_inOverflowRelayout = true; renderer()->setNeedsLayout(true, false); if (renderer()->isRenderBlock()) toRenderBlock(renderer())->layoutBlock(true); else renderer()->layout(); m_inOverflowRelayout = false; } } } // If overflow:scroll is turned into overflow:auto a bar might still be disabled (Bug 11985). if (m_hBar && box->hasAutoHorizontalScrollbar()) m_hBar->setEnabled(true); if (m_vBar && box->hasAutoVerticalScrollbar()) m_vBar->setEnabled(true); // Set up the range (and page step/line step). if (m_hBar) { int clientWidth = box->clientWidth(); int pageStep = (clientWidth - cAmountToKeepWhenPaging); if (pageStep < 0) pageStep = clientWidth; m_hBar->setSteps(cScrollbarPixelsPerLineStep, pageStep); m_hBar->setProportion(clientWidth, m_scrollWidth); m_hBar->setValue(scrollXOffset()); } if (m_vBar) { int clientHeight = box->clientHeight(); int pageStep = (clientHeight - cAmountToKeepWhenPaging); if (pageStep < 0) pageStep = clientHeight; m_vBar->setSteps(cScrollbarPixelsPerLineStep, pageStep); m_vBar->setProportion(clientHeight, m_scrollHeight); } if (renderer()->node() && renderer()->document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER)) updateOverflowStatus(horizontalOverflow, verticalOverflow);}void RenderLayer::paintOverflowControls(GraphicsContext* context, int tx, int ty, const IntRect& damageRect){ // Don't do anything if we have no overflow. if (!renderer()->hasOverflowClip()) return; // Move the scrollbar widgets if necessary. We normally move and resize widgets during layout, but sometimes // widgets can move without layout occurring (most notably when you scroll a document that // contains fixed positioned elements). positionOverflowControls(tx, ty); // Now that we're sure the scrollbars are in the right place, paint them. if (m_hBar) m_hBar->paint(context, damageRect); if (m_vBar) m_vBar->paint(context, damageRect); // We fill our scroll corner with white if we have a scrollbar that doesn't run all the way up to the // edge of the box. paintScrollCorner(context, tx, ty, damageRect); // Paint our resizer last, since it sits on top of the scroll corner. paintResizer(context, tx, ty, damageRect);}void RenderLayer::paintScrollCorner(GraphicsContext* context, int tx, int ty, const IntRect& damageRect){ RenderBox* box = renderBox(); ASSERT(box); IntRect cornerRect = scrollCornerRect(this, box->borderBoxRect()); IntRect absRect = IntRect(cornerRect.x() + tx, cornerRect.y() + ty, cornerRect.width(), cornerRect.height()); if (!absRect.intersects(damageRect)) return; if (context->updatingControlTints()) { updateScrollCornerStyle(); return; } if (m_scrollCorner) { m_scrollCorner->paintIntoRect(context, tx, ty, absRect); return; } context->fillRect(absRect, Color::white);}void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const IntRect& damageRect){ if (renderer()->style()->resize() == RESIZE_NONE) return; RenderBox* box = renderBox(); ASSERT(box); IntRect cornerRect = resizerCornerRect(this, box->borderBoxRect()); IntRect absRect = IntRect(cornerRect.x() + tx, cornerRect.y() + ty, cornerRect.width(), cornerRect.height()); if (!absRect.intersects(damageRect)) return; if (context->updatingControlTints()) { updateResizerStyle(); return; } if (m_resizer) { m_resizer->paintIntoRect(context, tx, ty, absRect); return; } // Paint the resizer control. DEFINE_STATIC_LOCAL(RefPtr<Image>, resizeCornerImage, (Image::loadPlatformResource("textAreaResizeCorner"))); IntPoint imagePoint(absRect.right() - resizeCornerImage->width(), absRect.bottom() - resizeCornerImage->height()); context->drawImage(resizeCornerImage.get(), imagePoint); // Draw a frame around the resizer (1px grey line) if there are any scrollbars present. // Clipping will exclude the right and bottom edges of this frame. if (m_hBar || m_vBar) { context->save(); context->clip(absRect)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -