15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008 Apple Inc. All Rights Reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008, 2009 Google Inc.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
28a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/scroll/ScrollbarThemeNonMacCommon.h"
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/PlatformMouseEvent.h"
31a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GraphicsContextStateSaver.h"
32a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/scroll/ScrollableArea.h"
331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/scroll/ScrollbarThemeClient.h"
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
35c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
37e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)bool ScrollbarThemeNonMacCommon::hasThumb(ScrollbarThemeClient* scrollbar)
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // This method is just called as a paint-time optimization to see if
40e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // painting the thumb can be skipped. We don't have to be exact here.
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return thumbLength(scrollbar) > 0;
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
44e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)IntRect ScrollbarThemeNonMacCommon::backButtonRect(ScrollbarThemeClient* scrollbar, ScrollbarPart part, bool)
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Windows and Linux just have single arrows.
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (part == BackButtonEndPart)
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return IntRect();
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IntSize size = buttonSize(scrollbar);
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return IntRect(scrollbar->x(), scrollbar->y(), size.width(), size.height());
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
54e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)IntRect ScrollbarThemeNonMacCommon::forwardButtonRect(ScrollbarThemeClient* scrollbar, ScrollbarPart part, bool)
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Windows and Linux just have single arrows.
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (part == ForwardButtonStartPart)
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return IntRect();
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IntSize size = buttonSize(scrollbar);
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int x, y;
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (scrollbar->orientation() == HorizontalScrollbar) {
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        x = scrollbar->x() + scrollbar->width() - size.width();
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        y = scrollbar->y();
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        x = scrollbar->x();
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        y = scrollbar->y() + scrollbar->height() - size.height();
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return IntRect(x, y, size.width(), size.height());
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
72e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)IntRect ScrollbarThemeNonMacCommon::trackRect(ScrollbarThemeClient* scrollbar, bool)
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IntSize bs = buttonSize(scrollbar);
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int thickness = scrollbarThickness(scrollbar->controlSize());
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (scrollbar->orientation() == HorizontalScrollbar) {
77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // Once the scrollbar becomes smaller than the size of the
78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // two buttons with a 1 pixel gap, the track disappears.
79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (scrollbar->width() <= 2 * bs.width() + 1)
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return IntRect();
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return IntRect(scrollbar->x() + bs.width(), scrollbar->y(), scrollbar->width() - 2 * bs.width(), thickness);
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (scrollbar->height() <= 2 * bs.height() + 1)
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return IntRect();
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return IntRect(scrollbar->x(), scrollbar->y() + bs.height(), thickness, scrollbar->height() - 2 * bs.height());
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
88e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)void ScrollbarThemeNonMacCommon::paintTrackBackground(GraphicsContext* context, ScrollbarThemeClient* scrollbar, const IntRect& rect)
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
90e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // Just assume a forward track part. We only paint the track as a single piece when there is no thumb.
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!hasThumb(scrollbar))
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        paintTrackPiece(context, scrollbar, rect, ForwardTrackPart);
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
95e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)void ScrollbarThemeNonMacCommon::paintTickmarks(GraphicsContext* context, ScrollbarThemeClient* scrollbar, const IntRect& rect)
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (scrollbar->orientation() != VerticalScrollbar)
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (rect.height() <= 0 || rect.width() <= 0)
101e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        return;
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Get the tickmarks for the frameview.
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<IntRect> tickmarks;
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    scrollbar->getTickmarks(tickmarks);
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!tickmarks.size())
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    GraphicsContextStateSaver stateSaver(*context);
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    context->setShouldAntialias(false);
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (Vector<IntRect>::const_iterator i = tickmarks.begin(); i != tickmarks.end(); ++i) {
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Calculate how far down (in %) the tick-mark should appear.
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const float percent = static_cast<float>(i->y()) / scrollbar->totalSize();
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Calculate how far down (in pixels) the tick-mark should appear.
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const int yPos = rect.y() + (rect.height() * percent);
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1195267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        context->setFillColor(Color(0xCC, 0xAA, 0x00, 0xFF));
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        FloatRect tickRect(rect.x(), yPos, rect.width(), 3);
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        context->fillRect(tickRect);
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1235267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        context->setFillColor(Color(0xFF, 0xDD, 0x00, 0xFF));
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        FloatRect tickStroke(rect.x(), yPos + 1, rect.width(), 1);
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        context->fillRect(tickStroke);
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
129c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
130