15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderScrollbar.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 295267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "core/css/PseudoStyleRequest.h" 3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/Frame.h" 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/FrameView.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderPart.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderScrollbarPart.h" 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderScrollbarTheme.h" 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<Scrollbar> RenderScrollbar::createCustomScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, Node* ownerNode, Frame* owningFrame) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return adoptRef(new RenderScrollbar(scrollableArea, orientation, ownerNode, owningFrame)); 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderScrollbar::RenderScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, Node* ownerNode, Frame* owningFrame) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : Scrollbar(scrollableArea, orientation, RegularScrollbar, RenderScrollbarTheme::renderScrollbarTheme()) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_owner(ownerNode) 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_owningFrame(owningFrame) 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(ownerNode || owningFrame); 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: We need to do this because RenderScrollbar::styleChanged is called as soon as the scrollbar is created. 5102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Update the scrollbar size. 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int width = 0; 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int height = 0; 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(ScrollbarBGPart); 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RenderScrollbarPart* part = m_parts.get(ScrollbarBGPart)) { 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) part->layout(); 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) width = part->width(); 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) height = part->height(); 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (this->orientation() == HorizontalScrollbar) 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) width = this->width(); 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) height = this->height(); 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setFrameRect(IntRect(0, 0, width, height)); 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderScrollbar::~RenderScrollbar() 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_parts.isEmpty()) { 7102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // When a scrollbar is detached from its parent (causing all parts removal) and 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // ready to be destroyed, its destruction can be delayed because of RefPtr 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // maintained in other classes such as EventHandler (m_lastScrollbarUnderMouse). 7402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // Meanwhile, we can have a call to updateScrollbarPart which recreates the 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // scrollbar part. So, we need to destroy these parts since we don't want them 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // to call on a destroyed scrollbar. See webkit bug 68009. 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarParts(true); 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderBox* RenderScrollbar::owningRenderer() const 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_owningFrame) { 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBox* currentRenderer = m_owningFrame->ownerRenderer(); 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return currentRenderer; 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_owner && m_owner->renderer() ? m_owner->renderer()->enclosingBox() : 0; 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderScrollbar::setParent(ScrollView* parent) 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Scrollbar::setParent(parent); 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!parent) { 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Destroy all of the scrollbar's RenderBoxes. 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarParts(true); 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderScrollbar::setEnabled(bool e) 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool wasEnabled = enabled(); 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Scrollbar::setEnabled(e); 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (wasEnabled != e) 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarParts(); 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderScrollbar::styleChanged() 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarParts(); 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderScrollbar::paint(GraphicsContext* context, const IntRect& damageRect) 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (context->updatingControlTints()) { 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarParts(); 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Scrollbar::paint(context, damageRect); 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderScrollbar::setHoveredPart(ScrollbarPart part) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (part == m_hoveredPart) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ScrollbarPart oldPart = m_hoveredPart; 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hoveredPart = part; 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(oldPart); 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(m_hoveredPart); 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(ScrollbarBGPart); 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(TrackBGPart); 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderScrollbar::setPressedPart(ScrollbarPart part) 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ScrollbarPart oldPart = m_pressedPart; 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Scrollbar::setPressedPart(part); 14002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(oldPart); 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(part); 14302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(ScrollbarBGPart); 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(TrackBGPart); 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<RenderStyle> RenderScrollbar::getScrollbarPseudoStyle(ScrollbarPart partType, PseudoId pseudoId) 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!owningRenderer()) 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) RefPtr<RenderStyle> result = owningRenderer()->getUncachedPseudoStyle(PseudoStyleRequest(pseudoId, this, partType), owningRenderer()->style()); 15402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch // Scrollbars for root frames should always have background color 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // unless explicitly specified as transparent. So we force it. 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This is because WebKit assumes scrollbar to be always painted and missing background 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // causes visual artifact like non-repainted dirty region. 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result && m_owningFrame && m_owningFrame->view() && !m_owningFrame->view()->isTransparent() && !result->hasBackground()) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result->setBackgroundColor(Color::white); 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderScrollbar::updateScrollbarParts(bool destroy) 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(ScrollbarBGPart, destroy); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(BackButtonStartPart, destroy); 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(ForwardButtonStartPart, destroy); 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(BackTrackPart, destroy); 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(ThumbPart, destroy); 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(ForwardTrackPart, destroy); 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(BackButtonEndPart, destroy); 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(ForwardButtonEndPart, destroy); 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateScrollbarPart(TrackBGPart, destroy); 17502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (destroy) 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // See if the scrollbar's thickness changed. If so, we need to mark our owning object as needing a layout. 18002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch bool isHorizontal = orientation() == HorizontalScrollbar; 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int oldThickness = isHorizontal ? height() : width(); 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int newThickness = 0; 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderScrollbarPart* part = m_parts.get(ScrollbarBGPart); 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (part) { 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) part->layout(); 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newThickness = isHorizontal ? part->height() : part->width(); 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (newThickness != oldThickness) { 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setFrameRect(IntRect(location(), IntSize(isHorizontal ? width() : newThickness, isHorizontal ? newThickness : height()))); 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RenderBox* box = owningRenderer()) 192d24c94b5090b6aa121f0f82325c9379004dc3196Ben Murdoch box->setChildNeedsLayout(); 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static PseudoId pseudoForScrollbarPart(ScrollbarPart part) 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (part) { 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case BackButtonStartPart: 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ForwardButtonStartPart: 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case BackButtonEndPart: 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ForwardButtonEndPart: 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return SCROLLBAR_BUTTON; 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case BackTrackPart: 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ForwardTrackPart: 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return SCROLLBAR_TRACK_PIECE; 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ThumbPart: 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return SCROLLBAR_THUMB; 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TrackBGPart: 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return SCROLLBAR_TRACK; 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ScrollbarBGPart: 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return SCROLLBAR; 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case NoPart: 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case AllParts: 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return SCROLLBAR; 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderScrollbar::updateScrollbarPart(ScrollbarPart partType, bool destroy) 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (partType == NoPart) 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<RenderStyle> partStyle = !destroy ? getScrollbarPseudoStyle(partType, pseudoForScrollbarPart(partType)) : PassRefPtr<RenderStyle>(0); 22702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool needRenderer = !destroy && partStyle && partStyle->display() != NONE && partStyle->visibility() == VISIBLE; 22902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (needRenderer && partStyle->display() != BLOCK) { 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // See if we are a button that should not be visible according to OS settings. 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ScrollbarButtonsPlacement buttonsPlacement = theme()->buttonsPlacement(); 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (partType) { 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case BackButtonStartPart: 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) needRenderer = (buttonsPlacement == ScrollbarButtonsSingle || buttonsPlacement == ScrollbarButtonsDoubleStart || 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) buttonsPlacement == ScrollbarButtonsDoubleBoth); 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ForwardButtonStartPart: 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) needRenderer = (buttonsPlacement == ScrollbarButtonsDoubleStart || buttonsPlacement == ScrollbarButtonsDoubleBoth); 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case BackButtonEndPart: 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) needRenderer = (buttonsPlacement == ScrollbarButtonsDoubleEnd || buttonsPlacement == ScrollbarButtonsDoubleBoth); 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ForwardButtonEndPart: 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) needRenderer = (buttonsPlacement == ScrollbarButtonsSingle || buttonsPlacement == ScrollbarButtonsDoubleEnd || 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) buttonsPlacement == ScrollbarButtonsDoubleBoth); 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 25202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderScrollbarPart* partRenderer = m_parts.get(partType); 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!partRenderer && needRenderer) { 255926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) partRenderer = RenderScrollbarPart::createAnonymous(owningRenderer()->document(), this, partType); 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_parts.set(partType, partRenderer); 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (partRenderer && !needRenderer) { 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_parts.remove(partType); 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) partRenderer->destroy(); 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) partRenderer = 0; 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 26202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (partRenderer) 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) partRenderer->setStyle(partStyle.release()); 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderScrollbar::paintPart(GraphicsContext* graphicsContext, ScrollbarPart partType, const IntRect& rect) 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderScrollbarPart* partRenderer = m_parts.get(partType); 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!partRenderer) 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) partRenderer->paintIntoRect(graphicsContext, location(), rect); 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)IntRect RenderScrollbar::buttonRect(ScrollbarPart partType) 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderScrollbarPart* partRenderer = m_parts.get(partType); 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!partRenderer) 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntRect(); 28002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) partRenderer->layout(); 28202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isHorizontal = orientation() == HorizontalScrollbar; 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (partType == BackButtonStartPart) 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntRect(location(), IntSize(isHorizontal ? partRenderer->pixelSnappedWidth() : width(), isHorizontal ? height() : partRenderer->pixelSnappedHeight())); 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (partType == ForwardButtonEndPart) 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntRect(isHorizontal ? x() + width() - partRenderer->pixelSnappedWidth() : x(), 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isHorizontal ? y() : y() + height() - partRenderer->pixelSnappedHeight(), 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isHorizontal ? partRenderer->pixelSnappedWidth() : width(), 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isHorizontal ? height() : partRenderer->pixelSnappedHeight()); 29102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (partType == ForwardButtonStartPart) { 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect previousButton = buttonRect(BackButtonStartPart); 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntRect(isHorizontal ? x() + previousButton.width() : x(), 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isHorizontal ? y() : y() + previousButton.height(), 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isHorizontal ? partRenderer->pixelSnappedWidth() : width(), 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isHorizontal ? height() : partRenderer->pixelSnappedHeight()); 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 29902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect followingButton = buttonRect(ForwardButtonEndPart); 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntRect(isHorizontal ? x() + width() - followingButton.width() - partRenderer->pixelSnappedWidth() : x(), 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isHorizontal ? y() : y() + height() - followingButton.height() - partRenderer->pixelSnappedHeight(), 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isHorizontal ? partRenderer->pixelSnappedWidth() : width(), 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isHorizontal ? height() : partRenderer->pixelSnappedHeight()); 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)IntRect RenderScrollbar::trackRect(int startLength, int endLength) 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderScrollbarPart* part = m_parts.get(TrackBGPart); 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (part) 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) part->layout(); 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (orientation() == HorizontalScrollbar) { 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int marginLeft = part ? static_cast<int>(part->marginLeft()) : 0; 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int marginRight = part ? static_cast<int>(part->marginRight()) : 0; 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startLength += marginLeft; 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endLength += marginRight; 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int totalLength = startLength + endLength; 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntRect(x() + startLength, y(), width() - totalLength, height()); 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 32102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int marginTop = part ? static_cast<int>(part->marginTop()) : 0; 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int marginBottom = part ? static_cast<int>(part->marginBottom()) : 0; 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startLength += marginTop; 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endLength += marginBottom; 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int totalLength = startLength + endLength; 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntRect(x(), y() + startLength, width(), height() - totalLength); 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)IntRect RenderScrollbar::trackPieceRectWithMargins(ScrollbarPart partType, const IntRect& oldRect) 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderScrollbarPart* partRenderer = m_parts.get(partType); 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!partRenderer) 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return oldRect; 33602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) partRenderer->layout(); 33802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect rect = oldRect; 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (orientation() == HorizontalScrollbar) { 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rect.setX(rect.x() + partRenderer->marginLeft()); 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rect.setWidth(rect.width() - partRenderer->marginWidth()); 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rect.setY(rect.y() + partRenderer->marginTop()); 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rect.setHeight(rect.height() - partRenderer->marginHeight()); 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return rect; 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderScrollbar::minimumThumbLength() 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderScrollbarPart* partRenderer = m_parts.get(ThumbPart); 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!partRenderer) 35402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch return 0; 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) partRenderer->layout(); 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return orientation() == HorizontalScrollbar ? partRenderer->width() : partRenderer->height(); 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 360