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 
     29 #include "PaintInfo.h"
     30 #include "RenderScrollbar.h"
     31 #include "RenderScrollbarTheme.h"
     32 #include "RenderView.h"
     33 
     34 using namespace std;
     35 
     36 namespace WebCore {
     37 
     38 RenderScrollbarPart::RenderScrollbarPart(Node* node, RenderScrollbar* scrollbar, ScrollbarPart part)
     39     : RenderBlock(node)
     40     , m_scrollbar(scrollbar)
     41     , m_part(part)
     42 {
     43 }
     44 
     45 RenderScrollbarPart::~RenderScrollbarPart()
     46 {
     47 }
     48 
     49 void RenderScrollbarPart::layout()
     50 {
     51     setLocation(IntPoint()); // We don't worry about positioning ourselves.  We're just determining our minimum width/height.
     52     if (m_scrollbar->orientation() == HorizontalScrollbar)
     53         layoutHorizontalPart();
     54     else
     55         layoutVerticalPart();
     56 
     57     setNeedsLayout(false);
     58 }
     59 
     60 void RenderScrollbarPart::layoutHorizontalPart()
     61 {
     62     if (m_part == ScrollbarBGPart) {
     63         setWidth(m_scrollbar->width());
     64         computeScrollbarHeight();
     65     } else {
     66         computeScrollbarWidth();
     67         setHeight(m_scrollbar->height());
     68     }
     69 }
     70 
     71 void RenderScrollbarPart::layoutVerticalPart()
     72 {
     73     if (m_part == ScrollbarBGPart) {
     74         computeScrollbarWidth();
     75         setHeight(m_scrollbar->height());
     76     } else {
     77         setWidth(m_scrollbar->width());
     78         computeScrollbarHeight();
     79     }
     80 }
     81 
     82 static int calcScrollbarThicknessUsing(const Length& l, int containingLength)
     83 {
     84     if (l.isIntrinsicOrAuto())
     85         return ScrollbarTheme::nativeTheme()->scrollbarThickness();
     86     return l.calcMinValue(containingLength);
     87 }
     88 
     89 void RenderScrollbarPart::computeScrollbarWidth()
     90 {
     91     if (!m_scrollbar->owningRenderer())
     92         return;
     93     int visibleSize = m_scrollbar->owningRenderer()->width() - m_scrollbar->owningRenderer()->borderLeft() - m_scrollbar->owningRenderer()->borderRight();
     94     int w = calcScrollbarThicknessUsing(style()->width(), visibleSize);
     95     int minWidth = calcScrollbarThicknessUsing(style()->minWidth(), visibleSize);
     96     int maxWidth = style()->maxWidth().isUndefined() ? w : calcScrollbarThicknessUsing(style()->maxWidth(), visibleSize);
     97     setWidth(max(minWidth, min(maxWidth, w)));
     98 
     99     // Buttons and track pieces can all have margins along the axis of the scrollbar.
    100     m_marginLeft = style()->marginLeft().calcMinValue(visibleSize);
    101     m_marginRight = style()->marginRight().calcMinValue(visibleSize);
    102 }
    103 
    104 void RenderScrollbarPart::computeScrollbarHeight()
    105 {
    106     if (!m_scrollbar->owningRenderer())
    107         return;
    108     int visibleSize = m_scrollbar->owningRenderer()->height() -  m_scrollbar->owningRenderer()->borderTop() - m_scrollbar->owningRenderer()->borderBottom();
    109     int h = calcScrollbarThicknessUsing(style()->height(), visibleSize);
    110     int minHeight = calcScrollbarThicknessUsing(style()->minHeight(), visibleSize);
    111     int maxHeight = style()->maxHeight().isUndefined() ? h : calcScrollbarThicknessUsing(style()->maxHeight(), visibleSize);
    112     setHeight(max(minHeight, min(maxHeight, h)));
    113 
    114     // Buttons and track pieces can all have margins along the axis of the scrollbar.
    115     m_marginTop = style()->marginTop().calcMinValue(visibleSize);
    116     m_marginBottom = style()->marginBottom().calcMinValue(visibleSize);
    117 }
    118 
    119 void RenderScrollbarPart::computePreferredLogicalWidths()
    120 {
    121     if (!preferredLogicalWidthsDirty())
    122         return;
    123 
    124     m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = 0;
    125 
    126     setPreferredLogicalWidthsDirty(false);
    127 }
    128 
    129 void RenderScrollbarPart::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
    130 {
    131     RenderBlock::styleWillChange(diff, newStyle);
    132     setInline(false);
    133 }
    134 
    135 void RenderScrollbarPart::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
    136 {
    137     RenderBlock::styleDidChange(diff, oldStyle);
    138     setInline(false);
    139     setPositioned(false);
    140     setFloating(false);
    141     setHasOverflowClip(false);
    142     if (oldStyle && m_scrollbar && m_part != NoPart && diff >= StyleDifferenceRepaint)
    143         m_scrollbar->theme()->invalidatePart(m_scrollbar, m_part);
    144 }
    145 
    146 void RenderScrollbarPart::imageChanged(WrappedImagePtr image, const IntRect* rect)
    147 {
    148     if (m_scrollbar && m_part != NoPart)
    149         m_scrollbar->theme()->invalidatePart(m_scrollbar, m_part);
    150     else {
    151         if (FrameView* frameView = view()->frameView()) {
    152             if (frameView->isFrameViewScrollCorner(this)) {
    153                 frameView->invalidateScrollCorner();
    154                 return;
    155             }
    156         }
    157 
    158         RenderBlock::imageChanged(image, rect);
    159     }
    160 }
    161 
    162 void RenderScrollbarPart::paintIntoRect(GraphicsContext* graphicsContext, int tx, int ty, const IntRect& rect)
    163 {
    164     // Make sure our dimensions match the rect.
    165     setLocation(rect.x() - tx, rect.y() - ty);
    166     setWidth(rect.width());
    167     setHeight(rect.height());
    168 
    169     if (graphicsContext->paintingDisabled())
    170         return;
    171 
    172     // Now do the paint.
    173     PaintInfo paintInfo(graphicsContext, rect, PaintPhaseBlockBackground, false, 0, 0);
    174     paint(paintInfo, tx, ty);
    175     paintInfo.phase = PaintPhaseChildBlockBackgrounds;
    176     paint(paintInfo, tx, ty);
    177     paintInfo.phase = PaintPhaseFloat;
    178     paint(paintInfo, tx, ty);
    179     paintInfo.phase = PaintPhaseForeground;
    180     paint(paintInfo, tx, ty);
    181     paintInfo.phase = PaintPhaseOutline;
    182     paint(paintInfo, tx, ty);
    183 }
    184 
    185 }
    186