LayoutScrollbarPart* LayoutScrollbarPart::createAnonymous(Document* document, LayoutScrollbar* scrollbar, ScrollbarPart part) { LayoutScrollbarPart* layoutObject = new LayoutScrollbarPart(scrollbar, part); recordScrollbarPartStats(*document, part); layoutObject->setDocumentForAnonymous(document); return layoutObject; }
int LayoutScrollbar::minimumThumbLength() const { LayoutScrollbarPart* partLayoutObject = m_parts.get(ThumbPart); if (!partLayoutObject) return 0; partLayoutObject->layout(); return orientation() == HorizontalScrollbar ? partLayoutObject->size().width() : partLayoutObject->size().height(); }
void LayoutScrollbar::updateScrollbarPart(ScrollbarPart partType, bool destroy) { if (partType == NoPart) return; RefPtr<ComputedStyle> partStyle = !destroy ? getScrollbarPseudoStyle(partType, pseudoForScrollbarPart(partType)) : PassRefPtr<ComputedStyle>(nullptr); bool needLayoutObject = !destroy && partStyle && partStyle->display() != NONE; if (needLayoutObject && partStyle->display() != BLOCK) { // See if we are a button that should not be visible according to OS settings. ScrollbarButtonsPlacement buttonsPlacement = theme()->buttonsPlacement(); switch (partType) { case BackButtonStartPart: needLayoutObject = (buttonsPlacement == ScrollbarButtonsPlacementSingle || buttonsPlacement == ScrollbarButtonsPlacementDoubleStart || buttonsPlacement == ScrollbarButtonsPlacementDoubleBoth); break; case ForwardButtonStartPart: needLayoutObject = (buttonsPlacement == ScrollbarButtonsPlacementDoubleStart || buttonsPlacement == ScrollbarButtonsPlacementDoubleBoth); break; case BackButtonEndPart: needLayoutObject = (buttonsPlacement == ScrollbarButtonsPlacementDoubleEnd || buttonsPlacement == ScrollbarButtonsPlacementDoubleBoth); break; case ForwardButtonEndPart: needLayoutObject = (buttonsPlacement == ScrollbarButtonsPlacementSingle || buttonsPlacement == ScrollbarButtonsPlacementDoubleEnd || buttonsPlacement == ScrollbarButtonsPlacementDoubleBoth); break; default: break; } } LayoutScrollbarPart* partLayoutObject = m_parts.get(partType); if (!partLayoutObject && needLayoutObject) { partLayoutObject = LayoutScrollbarPart::createAnonymous(&owningLayoutObject()->document(), this, partType); m_parts.set(partType, partLayoutObject); } else if (partLayoutObject && !needLayoutObject) { m_parts.remove(partType); partLayoutObject->destroy(); partLayoutObject = 0; } if (partLayoutObject) partLayoutObject->setStyle(partStyle.release()); }
void LayoutScrollbar::updateScrollbarParts(bool destroy) { updateScrollbarPart(ScrollbarBGPart, destroy); updateScrollbarPart(BackButtonStartPart, destroy); updateScrollbarPart(ForwardButtonStartPart, destroy); updateScrollbarPart(BackTrackPart, destroy); updateScrollbarPart(ThumbPart, destroy); updateScrollbarPart(ForwardTrackPart, destroy); updateScrollbarPart(BackButtonEndPart, destroy); updateScrollbarPart(ForwardButtonEndPart, destroy); updateScrollbarPart(TrackBGPart, destroy); if (destroy) return; // See if the scrollbar's thickness changed. If so, we need to mark our // owning object as needing a layout. bool isHorizontal = orientation() == HorizontalScrollbar; int oldThickness = isHorizontal ? height() : width(); int newThickness = 0; LayoutScrollbarPart* part = m_parts.get(ScrollbarBGPart); if (part) { part->layout(); newThickness = (isHorizontal ? part->size().height() : part->size().width()).toInt(); } if (newThickness != oldThickness) { setFrameRect( IntRect(location(), IntSize(isHorizontal ? width() : newThickness, isHorizontal ? newThickness : height()))); if (LayoutBox* box = owningLayoutObjectWithinFrame()) { if (box->isLayoutBlock()) toLayoutBlock(box)->notifyScrollbarThicknessChanged(); box->setChildNeedsLayout(); if (m_scrollableArea) m_scrollableArea->setScrollCornerNeedsPaintInvalidation(); } } }
IntRect LayoutScrollbar::trackPieceRectWithMargins(ScrollbarPart partType, const IntRect& oldRect) const { LayoutScrollbarPart* partLayoutObject = m_parts.get(partType); if (!partLayoutObject) return oldRect; partLayoutObject->layout(); IntRect rect = oldRect; if (orientation() == HorizontalScrollbar) { rect.setX(rect.x() + partLayoutObject->marginLeft()); rect.setWidth(rect.width() - partLayoutObject->marginWidth()); } else { rect.setY(rect.y() + partLayoutObject->marginTop()); rect.setHeight(rect.height() - partLayoutObject->marginHeight()); } return rect; }
IntRect LayoutScrollbar::trackRect(int startLength, int endLength) const { LayoutScrollbarPart* part = m_parts.get(TrackBGPart); if (part) part->layout(); if (orientation() == HorizontalScrollbar) { int marginLeft = part ? part->marginLeft().toInt() : 0; int marginRight = part ? part->marginRight().toInt() : 0; startLength += marginLeft; endLength += marginRight; int totalLength = startLength + endLength; return IntRect(x() + startLength, y(), width() - totalLength, height()); } int marginTop = part ? part->marginTop().toInt() : 0; int marginBottom = part ? part->marginBottom().toInt() : 0; startLength += marginTop; endLength += marginBottom; int totalLength = startLength + endLength; return IntRect(x(), y() + startLength, width(), height() - totalLength); }
IntRect LayoutScrollbar::buttonRect(ScrollbarPart partType) const { LayoutScrollbarPart* partLayoutObject = m_parts.get(partType); if (!partLayoutObject) return IntRect(); partLayoutObject->layout(); bool isHorizontal = orientation() == HorizontalScrollbar; if (partType == BackButtonStartPart) return IntRect( location(), IntSize( isHorizontal ? partLayoutObject->pixelSnappedWidth() : width(), isHorizontal ? height() : partLayoutObject->pixelSnappedHeight())); if (partType == ForwardButtonEndPart) { return IntRect( isHorizontal ? x() + width() - partLayoutObject->pixelSnappedWidth() : x(), isHorizontal ? y() : y() + height() - partLayoutObject->pixelSnappedHeight(), isHorizontal ? partLayoutObject->pixelSnappedWidth() : width(), isHorizontal ? height() : partLayoutObject->pixelSnappedHeight()); } if (partType == ForwardButtonStartPart) { IntRect previousButton = buttonRect(BackButtonStartPart); return IntRect( isHorizontal ? x() + previousButton.width() : x(), isHorizontal ? y() : y() + previousButton.height(), isHorizontal ? partLayoutObject->pixelSnappedWidth() : width(), isHorizontal ? height() : partLayoutObject->pixelSnappedHeight()); } IntRect followingButton = buttonRect(ForwardButtonEndPart); return IntRect( isHorizontal ? x() + width() - followingButton.width() - partLayoutObject->pixelSnappedWidth() : x(), isHorizontal ? y() : y() + height() - followingButton.height() - partLayoutObject->pixelSnappedHeight(), isHorizontal ? partLayoutObject->pixelSnappedWidth() : width(), isHorizontal ? height() : partLayoutObject->pixelSnappedHeight()); }
void LayoutScrollbar::updateScrollbarPart(ScrollbarPart partType, bool destroy) { if (partType == NoPart) return; RefPtr<ComputedStyle> partStyle = !destroy ? getScrollbarPseudoStyle(partType, pseudoForScrollbarPart(partType)) : PassRefPtr<ComputedStyle>(nullptr); bool needLayoutObject = !destroy && partStyle && partStyle->display() != EDisplay::None; if (needLayoutObject && partStyle->display() != EDisplay::Block) { // See if we are a button that should not be visible according to OS // settings. WebScrollbarButtonsPlacement buttonsPlacement = theme().buttonsPlacement(); switch (partType) { case BackButtonStartPart: needLayoutObject = (buttonsPlacement == WebScrollbarButtonsPlacementSingle || buttonsPlacement == WebScrollbarButtonsPlacementDoubleStart || buttonsPlacement == WebScrollbarButtonsPlacementDoubleBoth); break; case ForwardButtonStartPart: needLayoutObject = (buttonsPlacement == WebScrollbarButtonsPlacementDoubleStart || buttonsPlacement == WebScrollbarButtonsPlacementDoubleBoth); break; case BackButtonEndPart: needLayoutObject = (buttonsPlacement == WebScrollbarButtonsPlacementDoubleEnd || buttonsPlacement == WebScrollbarButtonsPlacementDoubleBoth); break; case ForwardButtonEndPart: needLayoutObject = (buttonsPlacement == WebScrollbarButtonsPlacementSingle || buttonsPlacement == WebScrollbarButtonsPlacementDoubleEnd || buttonsPlacement == WebScrollbarButtonsPlacementDoubleBoth); break; default: break; } } LayoutScrollbarPart* partLayoutObject = m_parts.get(partType); if (!partLayoutObject && needLayoutObject && m_scrollableArea) { partLayoutObject = LayoutScrollbarPart::createAnonymous( &owningLayoutObject()->document(), m_scrollableArea, this, partType); m_parts.set(partType, partLayoutObject); setNeedsPaintInvalidation(partType); } else if (partLayoutObject && !needLayoutObject) { m_parts.remove(partType); partLayoutObject->destroy(); partLayoutObject = nullptr; if (!destroy) setNeedsPaintInvalidation(partType); } if (partLayoutObject) partLayoutObject->setStyleWithWritingModeOfParent(partStyle.release()); }