⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scrollbarthemecomposite.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
字号:
/* * Copyright (C) 2008 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */#include "config.h"#include "ScrollbarThemeComposite.h"#include "ChromeClient.h"#include "Frame.h"#include "FrameView.h"#include "GraphicsContext.h"#include "Page.h"#include "PlatformMouseEvent.h"#include "Scrollbar.h"#include "ScrollbarClient.h"#include "Settings.h"namespace WebCore {#if PLATFORM(WIN)static Page* pageForScrollView(ScrollView* view){    if (!view)        return 0;    if (!view->isFrameView())        return 0;    FrameView* frameView = static_cast<FrameView*>(view);    if (!frameView->frame())        return 0;    return frameView->frame()->page();}#endifbool ScrollbarThemeComposite::paint(Scrollbar* scrollbar, GraphicsContext* graphicsContext, const IntRect& damageRect){    // Create the ScrollbarControlPartMask based on the damageRect    ScrollbarControlPartMask scrollMask = NoPart;    IntRect backButtonStartPaintRect;    IntRect backButtonEndPaintRect;    IntRect forwardButtonStartPaintRect;    IntRect forwardButtonEndPaintRect;    if (hasButtons(scrollbar)) {        backButtonStartPaintRect = backButtonRect(scrollbar, BackButtonStartPart, true);        if (damageRect.intersects(backButtonStartPaintRect))            scrollMask |= BackButtonStartPart;        backButtonEndPaintRect = backButtonRect(scrollbar, BackButtonEndPart, true);        if (damageRect.intersects(backButtonEndPaintRect))            scrollMask |= BackButtonEndPart;        forwardButtonStartPaintRect = forwardButtonRect(scrollbar, ForwardButtonStartPart, true);        if (damageRect.intersects(forwardButtonStartPaintRect))            scrollMask |= ForwardButtonStartPart;        forwardButtonEndPaintRect = forwardButtonRect(scrollbar, ForwardButtonEndPart, true);        if (damageRect.intersects(forwardButtonEndPaintRect))            scrollMask |= ForwardButtonEndPart;    }    IntRect startTrackRect;    IntRect thumbRect;    IntRect endTrackRect;    IntRect trackPaintRect = trackRect(scrollbar, true);    if (damageRect.intersects(trackPaintRect))        scrollMask |= TrackBGPart;    bool thumbPresent = hasThumb(scrollbar);    if (thumbPresent) {        IntRect track = trackRect(scrollbar);        splitTrack(scrollbar, track, startTrackRect, thumbRect, endTrackRect);        if (damageRect.intersects(thumbRect))            scrollMask |= ThumbPart;        if (damageRect.intersects(startTrackRect))            scrollMask |= BackTrackPart;        if (damageRect.intersects(endTrackRect))            scrollMask |= ForwardTrackPart;    } #if PLATFORM(WIN)    // FIXME: This API makes the assumption that the custom scrollbar's metrics will match    // the theme's metrics.  This is not a valid assumption.  The ability for a client to paint    // custom scrollbars should be removed once scrollbars can be styled via CSS.    if (Page* page = pageForScrollView(scrollbar->parent())) {        if (page->settings()->shouldPaintCustomScrollbars()) {            float proportion = static_cast<float>(scrollbar->visibleSize()) / scrollbar->totalSize();            float value = scrollbar->currentPos() / static_cast<float>(scrollbar->maximum());            ScrollbarControlState s = 0;            if (scrollbar->client()->isActive())                s |= ActiveScrollbarState;            if (scrollbar->enabled())                s |= EnabledScrollbarState;            if (scrollbar->pressedPart() != NoPart)                s |= PressedScrollbarState;            if (page->chrome()->client()->paintCustomScrollbar(graphicsContext,                                                               scrollbar->frameRect(),                                                                scrollbar->controlSize(),                                                               s,                                                                scrollbar->pressedPart(),                                                                scrollbar->orientation() == VerticalScrollbar,                                                               value,                                                               proportion,                                                               scrollMask))                return true;        }    }#endif    // Paint the scrollbar background (only used by custom CSS scrollbars).    paintScrollbarBackground(graphicsContext, scrollbar);    // Paint the back and forward buttons.    if (scrollMask & BackButtonStartPart)        paintButton(graphicsContext, scrollbar, backButtonStartPaintRect, BackButtonStartPart);    if (scrollMask & BackButtonEndPart)        paintButton(graphicsContext, scrollbar, backButtonEndPaintRect, BackButtonEndPart);    if (scrollMask & ForwardButtonStartPart)        paintButton(graphicsContext, scrollbar, forwardButtonStartPaintRect, ForwardButtonStartPart);    if (scrollMask & ForwardButtonEndPart)        paintButton(graphicsContext, scrollbar, forwardButtonEndPaintRect, ForwardButtonEndPart);        if (scrollMask & TrackBGPart)        paintTrackBackground(graphicsContext, scrollbar, trackPaintRect);        if ((scrollMask & ForwardTrackPart) || (scrollMask & BackTrackPart)) {        // Paint the track pieces above and below the thumb.        if (scrollMask & BackTrackPart)            paintTrackPiece(graphicsContext, scrollbar, startTrackRect, BackTrackPart);        if (scrollMask & ForwardTrackPart)            paintTrackPiece(graphicsContext, scrollbar, endTrackRect, ForwardTrackPart);        paintTickmarks(graphicsContext, scrollbar, trackPaintRect);    }    // Paint the thumb.    if (scrollMask & ThumbPart)        paintThumb(graphicsContext, scrollbar, thumbRect);    return true;}ScrollbarPart ScrollbarThemeComposite::hitTest(Scrollbar* scrollbar, const PlatformMouseEvent& evt){    ScrollbarPart result = NoPart;    if (!scrollbar->enabled())        return result;    IntPoint mousePosition = scrollbar->convertFromContainingWindow(evt.pos());    mousePosition.move(scrollbar->x(), scrollbar->y());        if (!scrollbar->frameRect().contains(mousePosition))        return NoPart;    result = ScrollbarBGPart;    IntRect track = trackRect(scrollbar);    if (track.contains(mousePosition)) {        IntRect beforeThumbRect;        IntRect thumbRect;        IntRect afterThumbRect;        splitTrack(scrollbar, track, beforeThumbRect, thumbRect, afterThumbRect);        if (thumbRect.contains(mousePosition))            result = ThumbPart;        else if (beforeThumbRect.contains(mousePosition))            result = BackTrackPart;        else if (afterThumbRect.contains(mousePosition))            result = ForwardTrackPart;        else            result = TrackBGPart;    } else if (backButtonRect(scrollbar, BackButtonStartPart).contains(mousePosition))        result = BackButtonStartPart;    else if (backButtonRect(scrollbar, BackButtonEndPart).contains(mousePosition))        result = BackButtonEndPart;    else if (forwardButtonRect(scrollbar, ForwardButtonStartPart).contains(mousePosition))        result = ForwardButtonStartPart;    else if (forwardButtonRect(scrollbar, ForwardButtonEndPart).contains(mousePosition))        result = ForwardButtonEndPart;    return result;}void ScrollbarThemeComposite::invalidatePart(Scrollbar* scrollbar, ScrollbarPart part){    if (part == NoPart)        return;    IntRect result;        switch (part) {        case BackButtonStartPart:            result = backButtonRect(scrollbar, BackButtonStartPart, true);            break;        case BackButtonEndPart:            result = backButtonRect(scrollbar, BackButtonEndPart, true);            break;        case ForwardButtonStartPart:            result = forwardButtonRect(scrollbar, ForwardButtonStartPart, true);            break;        case ForwardButtonEndPart:            result = forwardButtonRect(scrollbar, ForwardButtonEndPart, true);            break;        case TrackBGPart:            result = trackRect(scrollbar, true);            break;        case ScrollbarBGPart:            result = scrollbar->frameRect();            break;        default: {            IntRect beforeThumbRect, thumbRect, afterThumbRect;            splitTrack(scrollbar, trackRect(scrollbar), beforeThumbRect, thumbRect, afterThumbRect);            if (part == BackTrackPart)                result = beforeThumbRect;            else if (part == ForwardTrackPart)                result = afterThumbRect;            else                result = thumbRect;        }    }    result.move(-scrollbar->x(), -scrollbar->y());    scrollbar->invalidateRect(result);}void ScrollbarThemeComposite::splitTrack(Scrollbar* scrollbar, const IntRect& unconstrainedTrackRect, IntRect& beforeThumbRect, IntRect& thumbRect, IntRect& afterThumbRect){    // This function won't even get called unless we're big enough to have some combination of these three rects where at least    // one of them is non-empty.    IntRect trackRect = constrainTrackRectToTrackPieces(scrollbar, unconstrainedTrackRect);    int thickness = scrollbar->orientation() == HorizontalScrollbar ? scrollbar->height() : scrollbar->width();    int thumbPos = thumbPosition(scrollbar);    if (scrollbar->orientation() == HorizontalScrollbar) {        thumbRect = IntRect(trackRect.x() + thumbPos, trackRect.y() + (trackRect.height() - thickness) / 2, thumbLength(scrollbar), thickness);         beforeThumbRect = IntRect(trackRect.x(), trackRect.y(), thumbPos + thumbRect.width() / 2, trackRect.height());         afterThumbRect = IntRect(trackRect.x() + beforeThumbRect.width(), trackRect.y(), trackRect.right() - beforeThumbRect.right(), trackRect.height());    } else {        thumbRect = IntRect(trackRect.x() + (trackRect.width() - thickness) / 2, trackRect.y() + thumbPos, thickness, thumbLength(scrollbar));        beforeThumbRect = IntRect(trackRect.x(), trackRect.y(), trackRect.width(), thumbPos + thumbRect.height() / 2);         afterThumbRect = IntRect(trackRect.x(), trackRect.y() + beforeThumbRect.height(), trackRect.width(), trackRect.bottom() - beforeThumbRect.bottom());    }}int ScrollbarThemeComposite::thumbPosition(Scrollbar* scrollbar){    if (scrollbar->enabled())        return scrollbar->currentPos() * (trackLength(scrollbar) - thumbLength(scrollbar)) / scrollbar->maximum();    return 0;}int ScrollbarThemeComposite::thumbLength(Scrollbar* scrollbar){    if (!scrollbar->enabled())        return 0;    float proportion = (float)scrollbar->visibleSize() / scrollbar->totalSize();    int trackLen = trackLength(scrollbar);    int length = proportion * trackLen;    length = max(length, minimumThumbLength(scrollbar));    if (length > trackLen)        length = 0; // Once the thumb is below the track length, it just goes away (to make more room for the track).    return length;}int ScrollbarThemeComposite::minimumThumbLength(Scrollbar* scrollbar){    return scrollbarThickness(scrollbar->controlSize());}int ScrollbarThemeComposite::trackPosition(Scrollbar* scrollbar){    IntRect constrainedTrackRect = constrainTrackRectToTrackPieces(scrollbar, trackRect(scrollbar));    return (scrollbar->orientation() == HorizontalScrollbar) ? constrainedTrackRect.x() - scrollbar->x() : constrainedTrackRect.y() - scrollbar->y();}int ScrollbarThemeComposite::trackLength(Scrollbar* scrollbar){    IntRect constrainedTrackRect = constrainTrackRectToTrackPieces(scrollbar, trackRect(scrollbar));    return (scrollbar->orientation() == HorizontalScrollbar) ? constrainedTrackRect.width() : constrainedTrackRect.height();}void ScrollbarThemeComposite::paintScrollCorner(ScrollView* view, GraphicsContext* context, const IntRect& cornerRect){    FrameView* frameView = static_cast<FrameView*>(view);    Page* page = frameView->frame() ? frameView->frame()->page() : 0;    if (page && page->settings()->shouldPaintCustomScrollbars()) {        if (!page->chrome()->client()->paintCustomScrollCorner(context, cornerRect))            context->fillRect(cornerRect, Color::white);    }}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -