Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / 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 "core/rendering/RenderScrollbarPart.h"
28
29 #include "core/rendering/PaintInfo.h"
30 #include "core/rendering/RenderScrollbar.h"
31 #include "core/rendering/RenderScrollbarTheme.h"
32 #include "core/rendering/RenderView.h"
33 #include "platform/LengthFunctions.h"
34
35 namespace blink {
36
37 RenderScrollbarPart::RenderScrollbarPart(RenderScrollbar* scrollbar, ScrollbarPart part)
38     : RenderBlock(0)
39     , m_scrollbar(scrollbar)
40     , m_part(part)
41 {
42 }
43
44 RenderScrollbarPart::~RenderScrollbarPart()
45 {
46 }
47
48 RenderScrollbarPart* RenderScrollbarPart::createAnonymous(Document* document, RenderScrollbar* scrollbar, ScrollbarPart part)
49 {
50     RenderScrollbarPart* renderer = new RenderScrollbarPart(scrollbar, part);
51     renderer->setDocumentForAnonymous(document);
52     return renderer;
53 }
54
55 void RenderScrollbarPart::layout()
56 {
57     setLocation(LayoutPoint()); // We don't worry about positioning ourselves. We're just determining our minimum width/height.
58     if (m_scrollbar->orientation() == HorizontalScrollbar)
59         layoutHorizontalPart();
60     else
61         layoutVerticalPart();
62
63     clearNeedsLayout();
64 }
65
66 void RenderScrollbarPart::layoutHorizontalPart()
67 {
68     if (m_part == ScrollbarBGPart) {
69         setWidth(m_scrollbar->width());
70         computeScrollbarHeight();
71     } else {
72         computeScrollbarWidth();
73         setHeight(m_scrollbar->height());
74     }
75 }
76
77 void RenderScrollbarPart::layoutVerticalPart()
78 {
79     if (m_part == ScrollbarBGPart) {
80         computeScrollbarWidth();
81         setHeight(m_scrollbar->height());
82     } else {
83         setWidth(m_scrollbar->width());
84         computeScrollbarHeight();
85     }
86 }
87
88 static int calcScrollbarThicknessUsing(SizeType sizeType, const Length& length, int containingLength)
89 {
90     if (!length.isIntrinsicOrAuto() || (sizeType == MinSize && length.isAuto()))
91         return minimumValueForLength(length, containingLength);
92     return ScrollbarTheme::theme()->scrollbarThickness();
93 }
94
95 void RenderScrollbarPart::computeScrollbarWidth()
96 {
97     if (!m_scrollbar->owningRenderer())
98         return;
99     // FIXME: We are querying layout information but nothing guarantees that it's up-to-date, especially since we are called at style change.
100     // FIXME: Querying the style's border information doesn't work on table cells with collapsing borders.
101     int visibleSize = m_scrollbar->owningRenderer()->width() - m_scrollbar->owningRenderer()->style()->borderLeftWidth() - m_scrollbar->owningRenderer()->style()->borderRightWidth();
102     int w = calcScrollbarThicknessUsing(MainOrPreferredSize, style()->width(), visibleSize);
103     int minWidth = calcScrollbarThicknessUsing(MinSize, style()->minWidth(), visibleSize);
104     int maxWidth = style()->maxWidth().isUndefined() ? w : calcScrollbarThicknessUsing(MaxSize, style()->maxWidth(), visibleSize);
105     setWidth(std::max(minWidth, std::min(maxWidth, w)));
106
107     // Buttons and track pieces can all have margins along the axis of the scrollbar.
108     m_marginBox.setLeft(minimumValueForLength(style()->marginLeft(), visibleSize));
109     m_marginBox.setRight(minimumValueForLength(style()->marginRight(), visibleSize));
110 }
111
112 void RenderScrollbarPart::computeScrollbarHeight()
113 {
114     if (!m_scrollbar->owningRenderer())
115         return;
116     // FIXME: We are querying layout information but nothing guarantees that it's up-to-date, especially since we are called at style change.
117     // FIXME: Querying the style's border information doesn't work on table cells with collapsing borders.
118     int visibleSize = m_scrollbar->owningRenderer()->height() -  m_scrollbar->owningRenderer()->style()->borderTopWidth() - m_scrollbar->owningRenderer()->style()->borderBottomWidth();
119     int h = calcScrollbarThicknessUsing(MainOrPreferredSize, style()->height(), visibleSize);
120     int minHeight = calcScrollbarThicknessUsing(MinSize, style()->minHeight(), visibleSize);
121     int maxHeight = style()->maxHeight().isUndefined() ? h : calcScrollbarThicknessUsing(MaxSize, style()->maxHeight(), visibleSize);
122     setHeight(std::max(minHeight, std::min(maxHeight, h)));
123
124     // Buttons and track pieces can all have margins along the axis of the scrollbar.
125     m_marginBox.setTop(minimumValueForLength(style()->marginTop(), visibleSize));
126     m_marginBox.setBottom(minimumValueForLength(style()->marginBottom(), visibleSize));
127 }
128
129 void RenderScrollbarPart::computePreferredLogicalWidths()
130 {
131     if (!preferredLogicalWidthsDirty())
132         return;
133
134     m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = 0;
135
136     clearPreferredLogicalWidthsDirty();
137 }
138
139 void RenderScrollbarPart::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
140 {
141     RenderBlock::styleWillChange(diff, newStyle);
142     setInline(false);
143 }
144
145 void RenderScrollbarPart::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
146 {
147     RenderBlock::styleDidChange(diff, oldStyle);
148     setInline(false);
149     clearPositionedState();
150     setFloating(false);
151     setHasOverflowClip(false);
152     if (oldStyle && m_scrollbar && m_part != NoPart && (diff.needsPaintInvalidation() || diff.needsLayout()))
153         m_scrollbar->theme()->invalidatePart(m_scrollbar, m_part);
154 }
155
156 void RenderScrollbarPart::imageChanged(WrappedImagePtr image, const IntRect* rect)
157 {
158     if (m_scrollbar && m_part != NoPart)
159         m_scrollbar->theme()->invalidatePart(m_scrollbar, m_part);
160     else {
161         if (FrameView* frameView = view()->frameView()) {
162             if (frameView->isFrameViewScrollCorner(this)) {
163                 frameView->invalidateScrollCorner(frameView->scrollCornerRect());
164                 return;
165             }
166         }
167
168         RenderBlock::imageChanged(image, rect);
169     }
170 }
171
172 void RenderScrollbarPart::paintIntoRect(GraphicsContext* graphicsContext, const LayoutPoint& paintOffset, const LayoutRect& rect)
173 {
174     // Make sure our dimensions match the rect.
175     setLocation(rect.location() - toSize(paintOffset));
176     setWidth(rect.width());
177     setHeight(rect.height());
178
179     // Now do the paint.
180     PaintInfo paintInfo(graphicsContext, pixelSnappedIntRect(rect), PaintPhaseBlockBackground, PaintBehaviorNormal);
181     paint(paintInfo, paintOffset);
182     paintInfo.phase = PaintPhaseChildBlockBackgrounds;
183     paint(paintInfo, paintOffset);
184     paintInfo.phase = PaintPhaseFloat;
185     paint(paintInfo, paintOffset);
186     paintInfo.phase = PaintPhaseForeground;
187     paint(paintInfo, paintOffset);
188     paintInfo.phase = PaintPhaseOutline;
189     paint(paintInfo, paintOffset);
190 }
191
192 RenderObject* RenderScrollbarPart::rendererOwningScrollbar() const
193 {
194     if (!m_scrollbar)
195         return 0;
196     return m_scrollbar->owningRenderer();
197 }
198
199 }