Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "RenderScrollbarPart.h"
     28 #include "RenderScrollbar.h"
     29 #include "RenderScrollbarTheme.h"
     30 #include "RenderView.h"
     31 
     32 using namespace std;
     33 
     34 namespace WebCore {
     35 
     36 RenderScrollbarPart::RenderScrollbarPart(Node* node, RenderScrollbar* scrollbar, ScrollbarPart part)
     37     : RenderBlock(node)
     38     , m_scrollbar(scrollbar)
     39     , m_part(part)
     40 {
     41 }
     42 
     43 RenderScrollbarPart::~RenderScrollbarPart()
     44 {
     45 }
     46 
     47 void RenderScrollbarPart::layout()
     48 {
     49     setLocation(IntPoint()); // We don't worry about positioning ourselves.  We're just determining our minimum width/height.
     50     if (m_scrollbar->orientation() == HorizontalScrollbar)
     51         layoutHorizontalPart();
     52     else
     53         layoutVerticalPart();
     54 
     55     setNeedsLayout(false);
     56 }
     57 
     58 void RenderScrollbarPart::layoutHorizontalPart()
     59 {
     60     if (m_part == ScrollbarBGPart) {
     61         setWidth(m_scrollbar->width());
     62         computeScrollbarHeight();
     63     } else {
     64         computeScrollbarWidth();
     65         setHeight(m_scrollbar->height());
     66     }
     67 }
     68 
     69 void RenderScrollbarPart::layoutVerticalPart()
     70 {
     71     if (m_part == ScrollbarBGPart) {
     72         computeScrollbarWidth();
     73         setHeight(m_scrollbar->height());
     74     } else {
     75         setWidth(m_scrollbar->width());
     76         computeScrollbarHeight();
     77     }
     78 }
     79 
     80 static int calcScrollbarThicknessUsing(const Length& l, int containingLength)
     81 {
     82     if (l.isIntrinsicOrAuto())
     83         return ScrollbarTheme::nativeTheme()->scrollbarThickness();
     84     return l.calcMinValue(containingLength);
     85 }
     86 
     87 void RenderScrollbarPart::computeScrollbarWidth()
     88 {
     89     int visibleSize = m_scrollbar->owningRenderer()->width() - m_scrollbar->owningRenderer()->borderLeft() - m_scrollbar->owningRenderer()->borderRight();
     90     int w = calcScrollbarThicknessUsing(style()->width(), visibleSize);
     91     int minWidth = calcScrollbarThicknessUsing(style()->minWidth(), visibleSize);
     92     int maxWidth = style()->maxWidth().isUndefined() ? w : calcScrollbarThicknessUsing(style()->maxWidth(), visibleSize);
     93     setWidth(max(minWidth, min(maxWidth, w)));
     94 
     95     // Buttons and track pieces can all have margins along the axis of the scrollbar.
     96     m_marginLeft = style()->marginLeft().calcMinValue(visibleSize);
     97     m_marginRight = style()->marginRight().calcMinValue(visibleSize);
     98 }
     99 
    100 void RenderScrollbarPart::computeScrollbarHeight()
    101 {
    102     int visibleSize = m_scrollbar->owningRenderer()->height() -  m_scrollbar->owningRenderer()->borderTop() - m_scrollbar->owningRenderer()->borderBottom();
    103     int h = calcScrollbarThicknessUsing(style()->height(), visibleSize);
    104     int minHeight = calcScrollbarThicknessUsing(style()->minHeight(), visibleSize);
    105     int maxHeight = style()->maxHeight().isUndefined() ? h : calcScrollbarThicknessUsing(style()->maxHeight(), visibleSize);
    106     setHeight(max(minHeight, min(maxHeight, h)));
    107 
    108     // Buttons and track pieces can all have margins along the axis of the scrollbar.
    109     m_marginTop = style()->marginTop().calcMinValue(visibleSize);
    110     m_marginBottom = style()->marginBottom().calcMinValue(visibleSize);
    111 }
    112 
    113 void RenderScrollbarPart::calcPrefWidths()
    114 {
    115     if (!prefWidthsDirty())
    116         return;
    117 
    118     m_minPrefWidth = m_maxPrefWidth = 0;
    119 
    120     setPrefWidthsDirty(false);
    121 }
    122 
    123 void RenderScrollbarPart::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
    124 {
    125     RenderBlock::styleWillChange(diff, newStyle);
    126     setInline(false);
    127 }
    128 
    129 void RenderScrollbarPart::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
    130 {
    131     RenderBlock::styleDidChange(diff, oldStyle);
    132     setInline(false);
    133     setPositioned(false);
    134     setFloating(false);
    135     setHasOverflowClip(false);
    136     if (oldStyle && m_scrollbar && m_part != NoPart && diff >= StyleDifferenceRepaint)
    137         m_scrollbar->theme()->invalidatePart(m_scrollbar, m_part);
    138 }
    139 
    140 void RenderScrollbarPart::imageChanged(WrappedImagePtr image, const IntRect* rect)
    141 {
    142     if (m_scrollbar && m_part != NoPart)
    143         m_scrollbar->theme()->invalidatePart(m_scrollbar, m_part);
    144     else {
    145         if (FrameView* frameView = view()->frameView()) {
    146             if (frameView->isFrameViewScrollCorner(this)) {
    147                 frameView->invalidateScrollCorner();
    148                 return;
    149             }
    150         }
    151 
    152         RenderBlock::imageChanged(image, rect);
    153     }
    154 }
    155 
    156 void RenderScrollbarPart::paintIntoRect(GraphicsContext* graphicsContext, int tx, int ty, const IntRect& rect)
    157 {
    158     // Make sure our dimensions match the rect.
    159     setLocation(rect.x() - tx, rect.y() - ty);
    160     setWidth(rect.width());
    161     setHeight(rect.height());
    162 
    163     if (graphicsContext->paintingDisabled())
    164         return;
    165 
    166     // Now do the paint.
    167     RenderObject::PaintInfo paintInfo(graphicsContext, rect, PaintPhaseBlockBackground, false, 0, 0);
    168     paint(paintInfo, tx, ty);
    169     paintInfo.phase = PaintPhaseChildBlockBackgrounds;
    170     paint(paintInfo, tx, ty);
    171     paintInfo.phase = PaintPhaseFloat;
    172     paint(paintInfo, tx, ty);
    173     paintInfo.phase = PaintPhaseForeground;
    174     paint(paintInfo, tx, ty);
    175     paintInfo.phase = PaintPhaseOutline;
    176     paint(paintInfo, tx, ty);
    177 }
    178 
    179 }
    180