void AsyncScrollingCoordinator::frameViewLayoutUpdated(FrameView* frameView)
{
    ASSERT(isMainThread());
    ASSERT(m_page);

    // If there isn't a root node yet, don't do anything. We'll be called again after creating one.
    if (!m_scrollingStateTree->rootStateNode())
        return;

    // Compute the region of the page that we can't do fast scrolling for. This currently includes
    // all scrollable areas, such as subframes, overflow divs and list boxes. We need to do this even if the
    // frame view whose layout was updated is not the main frame.
    // In the future, we may want to have the ability to set non-fast scrolling regions for more than
    // just the root node. But right now, this concept only applies to the root.
    if (frameView->frame().isMainFrame())
        m_scrollingStateTree->rootStateNode()->setNonFastScrollableRegion(computeNonFastScrollableRegion(&frameView->frame(), IntPoint()));

    if (!coordinatesScrollingForFrameView(frameView))
        return;

    ScrollingStateFrameScrollingNode* node = downcast<ScrollingStateFrameScrollingNode>(m_scrollingStateTree->stateNodeForID(frameView->scrollLayerID()));
    if (!node)
        return;

    Scrollbar* verticalScrollbar = frameView->verticalScrollbar();
    Scrollbar* horizontalScrollbar = frameView->horizontalScrollbar();
    node->setScrollbarPaintersFromScrollbars(verticalScrollbar, horizontalScrollbar);
    
    node->setFrameScaleFactor(frameView->frame().frameScaleFactor());
    node->setHeaderHeight(frameView->headerHeight());
    node->setFooterHeight(frameView->footerHeight());
    node->setTopContentInset(frameView->topContentInset());

    node->setScrollOrigin(frameView->scrollOrigin());
    node->setScrollableAreaSize(frameView->visibleContentRect().size());
    node->setTotalContentsSize(frameView->totalContentsSize());
    node->setReachableContentsSize(frameView->totalContentsSize());

#if ENABLE(CSS_SCROLL_SNAP)
    frameView->updateSnapOffsets();
    if (const Vector<LayoutUnit>* horizontalSnapOffsets = frameView->horizontalSnapOffsets())
        setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Horizontal, *horizontalSnapOffsets, m_page->deviceScaleFactor());

    if (const Vector<LayoutUnit>* verticalSnapOffsets = frameView->verticalSnapOffsets())
        setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Vertical, *verticalSnapOffsets, m_page->deviceScaleFactor());
#endif

    ScrollableAreaParameters scrollParameters;
    scrollParameters.horizontalScrollElasticity = frameView->horizontalScrollElasticity();
    scrollParameters.verticalScrollElasticity = frameView->verticalScrollElasticity();
    scrollParameters.hasEnabledHorizontalScrollbar = horizontalScrollbar && horizontalScrollbar->enabled();
    scrollParameters.hasEnabledVerticalScrollbar = verticalScrollbar && verticalScrollbar->enabled();
    scrollParameters.horizontalScrollbarMode = frameView->horizontalScrollbarMode();
    scrollParameters.verticalScrollbarMode = frameView->verticalScrollbarMode();

    node->setScrollableAreaParameters(scrollParameters);
}
Exemple #2
0
void ScrollbarThemeAura::paintTrackPiece(GraphicsContext& gc,
                                         const Scrollbar& scrollbar,
                                         const IntRect& rect,
                                         ScrollbarPart partType) {
  DisplayItem::Type displayItemType = trackPiecePartToDisplayItemType(partType);
  if (DrawingRecorder::useCachedDrawingIfPossible(gc, scrollbar,
                                                  displayItemType))
    return;

  DrawingRecorder recorder(gc, scrollbar, displayItemType, rect);

  WebThemeEngine::State state = scrollbar.hoveredPart() == partType
                                    ? WebThemeEngine::StateHover
                                    : WebThemeEngine::StateNormal;

  if (useMockTheme() && !scrollbar.enabled())
    state = WebThemeEngine::StateDisabled;

  IntRect alignRect = trackRect(scrollbar, false);
  WebThemeEngine::ExtraParams extraParams;
  extraParams.scrollbarTrack.isBack = (partType == BackTrackPart);
  extraParams.scrollbarTrack.trackX = alignRect.x();
  extraParams.scrollbarTrack.trackY = alignRect.y();
  extraParams.scrollbarTrack.trackWidth = alignRect.width();
  extraParams.scrollbarTrack.trackHeight = alignRect.height();
  Platform::current()->themeEngine()->paint(
      gc.canvas(), scrollbar.orientation() == HorizontalScrollbar
                       ? WebThemeEngine::PartScrollbarHorizontalTrack
                       : WebThemeEngine::PartScrollbarVerticalTrack,
      state, WebRect(rect), &extraParams);
}
void ScrollbarThemeWin::paintThumb(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& rect)
{
    checkAndInitScrollbarTheme();

    int state;
    if (!scrollbar.enabled())
        state = TS_DISABLED;
    else if (scrollbar.pressedPart() == ThumbPart)
        state = TS_ACTIVE; // Thumb always stays active once pressed.
    else if (scrollbar.hoveredPart() == ThumbPart)
        state = TS_HOVER;
    else
        state = TS_NORMAL;

    bool alphaBlend = false;
    if (scrollbarTheme)
        alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, scrollbar.orientation() == HorizontalScrollbar ? SP_THUMBHOR : SP_THUMBVERT, state);
    LocalWindowsContext windowsContext(context, rect, alphaBlend);
    RECT themeRect(rect);
    if (scrollbarTheme) {
        DrawThemeBackground(scrollbarTheme, windowsContext.hdc(), scrollbar.orientation() == HorizontalScrollbar ? SP_THUMBHOR : SP_THUMBVERT, state, &themeRect, 0);
        paintGripper(scrollbar, windowsContext.hdc(), gripperRect(scrollbarThickness(), rect));
    } else
        ::DrawEdge(windowsContext.hdc(), &themeRect, EDGE_RAISED, BF_RECT | BF_MIDDLE);

    if (!alphaBlend && !context.isInTransparencyLayer())
        DIBPixelData::setRGBABitmapAlpha(windowsContext.hdc(), rect, 255);
}
Exemple #4
0
void AsyncScrollingCoordinator::frameViewLayoutUpdated(FrameView* frameView)
{
    ASSERT(isMainThread());
    ASSERT(m_page);

    // If there isn't a root node yet, don't do anything. We'll be called again after creating one.
    if (!m_scrollingStateTree->rootStateNode())
        return;

    // Compute the region of the page that we can't do fast scrolling for. This currently includes
    // all scrollable areas, such as subframes, overflow divs and list boxes. We need to do this even if the
    // frame view whose layout was updated is not the main frame.
    Region nonFastScrollableRegion = computeNonFastScrollableRegion(&m_page->mainFrame(), IntPoint());

    // In the future, we may want to have the ability to set non-fast scrolling regions for more than
    // just the root node. But right now, this concept only applies to the root.
    setNonFastScrollableRegionForNode(nonFastScrollableRegion, m_scrollingStateTree->rootStateNode());

    if (!coordinatesScrollingForFrameView(frameView))
        return;

    ScrollingStateScrollingNode* node = toScrollingStateScrollingNode(m_scrollingStateTree->stateNodeForID(frameView->scrollLayerID()));
    if (!node)
        return;

    Scrollbar* verticalScrollbar = frameView->verticalScrollbar();
    Scrollbar* horizontalScrollbar = frameView->horizontalScrollbar();
    setScrollbarPaintersFromScrollbarsForNode(verticalScrollbar, horizontalScrollbar, node);

    node->setFrameScaleFactor(frameView->frame().frameScaleFactor());
    node->setHeaderHeight(frameView->headerHeight());
    node->setFooterHeight(frameView->footerHeight());

    node->setScrollOrigin(frameView->scrollOrigin());
    node->setViewportConstrainedObjectRect(FloatRect(FloatPoint(), frameView->visibleContentRect().size()));
    node->setTotalContentsSize(frameView->totalContentsSize());

    ScrollableAreaParameters scrollParameters;
    scrollParameters.horizontalScrollElasticity = frameView->horizontalScrollElasticity();
    scrollParameters.verticalScrollElasticity = frameView->verticalScrollElasticity();
    scrollParameters.hasEnabledHorizontalScrollbar = horizontalScrollbar && horizontalScrollbar->enabled();
    scrollParameters.hasEnabledVerticalScrollbar = verticalScrollbar && verticalScrollbar->enabled();
    scrollParameters.horizontalScrollbarMode = frameView->horizontalScrollbarMode();
    scrollParameters.verticalScrollbarMode = frameView->verticalScrollbarMode();

    node->setScrollableAreaParameters(scrollParameters);
}
void ScrollbarThemeWin::paintTrackPiece(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& rect, ScrollbarPart partType)
{
    checkAndInitScrollbarTheme();

    bool start = partType == BackTrackPart;
    int part;
    if (scrollbar.orientation() == HorizontalScrollbar)
        part = start ? SP_TRACKSTARTHOR : SP_TRACKENDHOR;
    else
        part = start ? SP_TRACKSTARTVERT : SP_TRACKENDVERT;

    int state;
    if (!scrollbar.enabled())
        state = TS_DISABLED;
    else if ((scrollbar.hoveredPart() == BackTrackPart && start) ||
             (scrollbar.hoveredPart() == ForwardTrackPart && !start))
        state = (scrollbar.pressedPart() == scrollbar.hoveredPart() ? TS_ACTIVE : TS_HOVER);
    else
        state = TS_NORMAL;

    bool alphaBlend = false;
    if (scrollbarTheme)
        alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, part, state);

    LocalWindowsContext windowsContext(context, rect, alphaBlend);
    RECT themeRect(rect);

    if (scrollbarTheme)
        DrawThemeBackground(scrollbarTheme, windowsContext.hdc(), part, state, &themeRect, 0);
    else {
        DWORD color3DFace = ::GetSysColor(COLOR_3DFACE);
        DWORD colorScrollbar = ::GetSysColor(COLOR_SCROLLBAR);
        DWORD colorWindow = ::GetSysColor(COLOR_WINDOW);
        HDC hdc = windowsContext.hdc();
        if ((color3DFace != colorScrollbar) && (colorWindow != colorScrollbar))
            ::FillRect(hdc, &themeRect, HBRUSH(COLOR_SCROLLBAR+1));
        else {
            static WORD patternBits[8] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 };
            auto patternBitmap = adoptGDIObject(::CreateBitmap(8, 8, 1, 1, patternBits));
            auto brush = adoptGDIObject(::CreatePatternBrush(patternBitmap.get()));
            SaveDC(hdc);
            ::SetTextColor(hdc, ::GetSysColor(COLOR_3DHILIGHT));
            ::SetBkColor(hdc, ::GetSysColor(COLOR_3DFACE));
            ::SetBrushOrgEx(hdc, rect.x(), rect.y(), NULL);
            ::SelectObject(hdc, brush.get());
            ::FillRect(hdc, &themeRect, brush.get());
            ::RestoreDC(hdc, -1);
        }
    }

    if (!alphaBlend && !context.isInTransparencyLayer())
        DIBPixelData::setRGBABitmapAlpha(windowsContext.hdc(), rect, 255);
}
void ScrollbarThemeWin::paintButton(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& rect, ScrollbarPart part)
{
    checkAndInitScrollbarTheme();

    bool start = (part == BackButtonStartPart);
    int xpState = 0;
    int classicState = 0;
    if (scrollbar.orientation() == HorizontalScrollbar)
        xpState = start ? TS_LEFT_BUTTON : TS_RIGHT_BUTTON;
    else
        xpState = start ? TS_UP_BUTTON : TS_DOWN_BUTTON;
    classicState = xpState / 4;

    if (!scrollbar.enabled()) {
        xpState += TS_DISABLED;
        classicState |= DFCS_INACTIVE;
    } else if ((scrollbar.hoveredPart() == BackButtonStartPart && start) ||
               (scrollbar.hoveredPart() == ForwardButtonEndPart && !start)) {
        if (scrollbar.pressedPart() == scrollbar.hoveredPart()) {
            xpState += TS_ACTIVE;
            classicState |= DFCS_PUSHED;
            classicState |= DFCS_FLAT;
        } else
            xpState += TS_HOVER;
    } else {
        if (scrollbar.hoveredPart() == NoPart || !runningVista)
            xpState += TS_NORMAL;
        else {
            if (scrollbar.orientation() == HorizontalScrollbar)
                xpState = start ? TS_LEFT_BUTTON_HOVER : TS_RIGHT_BUTTON_HOVER;
            else
                xpState = start ? TS_UP_BUTTON_HOVER : TS_DOWN_BUTTON_HOVER;
        }
    }

    bool alphaBlend = false;
    if (scrollbarTheme)
        alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, SP_BUTTON, xpState);

    LocalWindowsContext windowsContext(context, rect, alphaBlend);
    RECT themeRect(rect);
    if (scrollbarTheme)
        DrawThemeBackground(scrollbarTheme, windowsContext.hdc(), SP_BUTTON, xpState, &themeRect, 0);
    else
        ::DrawFrameControl(windowsContext.hdc(), &themeRect, DFC_SCROLL, classicState);

    if (!alphaBlend && !context.isInTransparencyLayer())
        DIBPixelData::setRGBABitmapAlpha(windowsContext.hdc(), rect, 255);
}
static void paintGripper(Scrollbar& scrollbar, HDC hdc, const IntRect& rect)
{
    if (!scrollbarTheme)
        return;  // Classic look has no gripper.
   
    int state;
    if (!scrollbar.enabled())
        state = TS_DISABLED;
    else if (scrollbar.pressedPart() == ThumbPart)
        state = TS_ACTIVE; // Thumb always stays active once pressed.
    else if (scrollbar.hoveredPart() == ThumbPart)
        state = TS_HOVER;
    else
        state = TS_NORMAL;

    RECT themeRect(rect);
    DrawThemeBackground(scrollbarTheme, hdc, scrollbar.orientation() == HorizontalScrollbar ? SP_GRIPPERHOR : SP_GRIPPERVERT, state, &themeRect, 0);
}
void AsyncScrollingCoordinator::frameViewLayoutUpdated(FrameView& frameView)
{
    ASSERT(isMainThread());
    ASSERT(m_page);

    // If there isn't a root node yet, don't do anything. We'll be called again after creating one.
    if (!m_scrollingStateTree->rootStateNode())
        return;

    // Compute the region of the page that we can't do fast scrolling for. This currently includes
    // all scrollable areas, such as subframes, overflow divs and list boxes. We need to do this even if the
    // frame view whose layout was updated is not the main frame.
    // In the future, we may want to have the ability to set non-fast scrolling regions for more than
    // just the root node. But right now, this concept only applies to the root.
    m_scrollingStateTree->rootStateNode()->setNonFastScrollableRegion(absoluteNonFastScrollableRegion());
    m_nonFastScrollableRegionDirty = false;

    if (!coordinatesScrollingForFrameView(frameView))
        return;

    ScrollingStateFrameScrollingNode* node = downcast<ScrollingStateFrameScrollingNode>(m_scrollingStateTree->stateNodeForID(frameView.scrollLayerID()));
    if (!node)
        return;

    Scrollbar* verticalScrollbar = frameView.verticalScrollbar();
    Scrollbar* horizontalScrollbar = frameView.horizontalScrollbar();
    node->setScrollbarPaintersFromScrollbars(verticalScrollbar, horizontalScrollbar);
    
    node->setFrameScaleFactor(frameView.frame().frameScaleFactor());
    node->setHeaderHeight(frameView.headerHeight());
    node->setFooterHeight(frameView.footerHeight());
    node->setTopContentInset(frameView.topContentInset());

    node->setScrollOrigin(frameView.scrollOrigin());
    node->setScrollableAreaSize(frameView.visibleContentRect().size());
    node->setTotalContentsSize(frameView.totalContentsSize());
    node->setReachableContentsSize(frameView.totalContentsSize());
    node->setFixedElementsLayoutRelativeToFrame(frameView.fixedElementsLayoutRelativeToFrame());

#if ENABLE(CSS_SCROLL_SNAP)
    frameView.updateSnapOffsets();
    updateScrollSnapPropertiesWithFrameView(frameView);
#endif

#if PLATFORM(COCOA)
    Page* page = frameView.frame().page();
    if (page && page->expectsWheelEventTriggers()) {
        LOG(WheelEventTestTriggers, "    AsyncScrollingCoordinator::frameViewLayoutUpdated: Expects wheel event test trigger=%d", page->expectsWheelEventTriggers());
        node->setExpectsWheelEventTestTrigger(page->expectsWheelEventTriggers());
    }
#endif

    ScrollableAreaParameters scrollParameters;
    scrollParameters.horizontalScrollElasticity = frameView.horizontalScrollElasticity();
    scrollParameters.verticalScrollElasticity = frameView.verticalScrollElasticity();
    scrollParameters.hasEnabledHorizontalScrollbar = horizontalScrollbar && horizontalScrollbar->enabled();
    scrollParameters.hasEnabledVerticalScrollbar = verticalScrollbar && verticalScrollbar->enabled();
    scrollParameters.horizontalScrollbarMode = frameView.horizontalScrollbarMode();
    scrollParameters.verticalScrollbarMode = frameView.verticalScrollbarMode();

    node->setScrollableAreaParameters(scrollParameters);
}
void ScrollbarThemeMock::paintThumb(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& thumbRect)
{
    if (scrollbar.enabled())
        context.fillRect(thumbRect, Color::darkGray, ColorSpaceDeviceRGB);
}
void ScrollbarThemeMock::paintTrackBackground(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& trackRect)
{
    context.fillRect(trackRect, scrollbar.enabled() ? Color::lightGray : Color(0xFFE0E0E0), ColorSpaceDeviceRGB);
}
bool ScrollbarThemeSafari::hasThumb(Scrollbar& scrollbar)
{
    return scrollbar.enabled() && (scrollbar.orientation() == HorizontalScrollbar ? 
             scrollbar.width() : 
             scrollbar.height()) >= 2 * cButtonInset[scrollbar.controlSize()] + cThumbMinLength[scrollbar.controlSize()] + 1;
}
bool ScrollbarThemeSafari::hasButtons(Scrollbar& scrollbar)
{
    return scrollbar.enabled() && (scrollbar.orientation() == HorizontalScrollbar ? 
             scrollbar.width() : 
             scrollbar.height()) >= 2 * (cRealButtonLength[scrollbar.controlSize()] - cButtonHitInset[scrollbar.controlSize()]);
}