initial import
[vuplus_webkit] / Source / WebCore / rendering / RenderScrollbarPart.cpp
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(LayoutPoint()); // 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, const LayoutPoint& paintOffset, const LayoutRect& rect)
163 {
164     // Make sure our dimensions match the rect.
165     setLocation(rect.location() - toSize(paintOffset));
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, paintOffset);
175     paintInfo.phase = PaintPhaseChildBlockBackgrounds;
176     paint(paintInfo, paintOffset);
177     paintInfo.phase = PaintPhaseFloat;
178     paint(paintInfo, paintOffset);
179     paintInfo.phase = PaintPhaseForeground;
180     paint(paintInfo, paintOffset);
181     paintInfo.phase = PaintPhaseOutline;
182     paint(paintInfo, paintOffset);
183 }
184
185 }