Support iconUrl of w3c Notification
[framework/web/webkit-efl.git] / 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(SizeType sizeType, const Length& length, int containingLength, RenderView* renderView)
83 {
84     if (!length.isIntrinsicOrAuto() || (sizeType == MinSize && length.isAuto()))
85         return minimumValueForLength(length, containingLength, renderView);
86     return ScrollbarTheme::theme()->scrollbarThickness();
87 }
88
89 void RenderScrollbarPart::computeScrollbarWidth()
90 {
91     if (!m_scrollbar->owningRenderer())
92         return;
93     RenderView* renderView = view();
94     int visibleSize = m_scrollbar->owningRenderer()->width() - m_scrollbar->owningRenderer()->borderLeft() - m_scrollbar->owningRenderer()->borderRight();
95     int w = calcScrollbarThicknessUsing(MainOrPreferredSize, style()->width(), visibleSize, renderView);
96     int minWidth = calcScrollbarThicknessUsing(MinSize, style()->minWidth(), visibleSize, renderView);
97     int maxWidth = style()->maxWidth().isUndefined() ? w : calcScrollbarThicknessUsing(MaxSize, style()->maxWidth(), visibleSize, renderView);
98     setWidth(max(minWidth, min(maxWidth, w)));
99     
100     // Buttons and track pieces can all have margins along the axis of the scrollbar. 
101     m_marginBox.setLeft(minimumValueForLength(style()->marginLeft(), visibleSize, renderView));
102     m_marginBox.setRight(minimumValueForLength(style()->marginRight(), visibleSize, renderView));
103 }
104
105 void RenderScrollbarPart::computeScrollbarHeight()
106 {
107     if (!m_scrollbar->owningRenderer())
108         return;
109     RenderView* renderView = view();
110     int visibleSize = m_scrollbar->owningRenderer()->height() -  m_scrollbar->owningRenderer()->borderTop() - m_scrollbar->owningRenderer()->borderBottom();
111     int h = calcScrollbarThicknessUsing(MainOrPreferredSize, style()->height(), visibleSize, renderView);
112     int minHeight = calcScrollbarThicknessUsing(MinSize, style()->minHeight(), visibleSize, renderView);
113     int maxHeight = style()->maxHeight().isUndefined() ? h : calcScrollbarThicknessUsing(MaxSize, style()->maxHeight(), visibleSize, renderView);
114     setHeight(max(minHeight, min(maxHeight, h)));
115
116     // Buttons and track pieces can all have margins along the axis of the scrollbar. 
117     m_marginBox.setTop(minimumValueForLength(style()->marginTop(), visibleSize, renderView));
118     m_marginBox.setBottom(minimumValueForLength(style()->marginBottom(), visibleSize, renderView));
119 }
120
121 void RenderScrollbarPart::computePreferredLogicalWidths()
122 {
123     if (!preferredLogicalWidthsDirty())
124         return;
125     
126     m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = 0;
127
128     setPreferredLogicalWidthsDirty(false);
129 }
130
131 void RenderScrollbarPart::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
132 {
133     RenderBlock::styleWillChange(diff, newStyle);
134     setInline(false);
135 }
136
137 void RenderScrollbarPart::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
138 {
139     RenderBlock::styleDidChange(diff, oldStyle);
140     setInline(false);
141     setPositioned(false);
142     setFloating(false);
143     setHasOverflowClip(false);
144     if (oldStyle && m_scrollbar && m_part != NoPart && diff >= StyleDifferenceRepaint)
145         m_scrollbar->theme()->invalidatePart(m_scrollbar, m_part);
146 }
147
148 void RenderScrollbarPart::imageChanged(WrappedImagePtr image, const IntRect* rect)
149 {
150     if (m_scrollbar && m_part != NoPart)
151         m_scrollbar->theme()->invalidatePart(m_scrollbar, m_part);
152     else {
153         if (FrameView* frameView = view()->frameView()) {
154             if (frameView->isFrameViewScrollCorner(this)) {
155                 frameView->invalidateScrollCorner(frameView->scrollCornerRect());
156                 return;
157             }
158         }
159         
160         RenderBlock::imageChanged(image, rect);
161     }
162 }
163
164 void RenderScrollbarPart::paintIntoRect(GraphicsContext* graphicsContext, const LayoutPoint& paintOffset, const LayoutRect& rect)
165 {
166     // Make sure our dimensions match the rect.
167     setLocation(rect.location() - toSize(paintOffset));
168     setWidth(rect.width());
169     setHeight(rect.height());
170
171     if (graphicsContext->paintingDisabled())
172         return;
173
174     // Now do the paint.
175     PaintInfo paintInfo(graphicsContext, pixelSnappedIntRect(rect), PaintPhaseBlockBackground, false, 0, 0, 0);
176     paint(paintInfo, paintOffset);
177     paintInfo.phase = PaintPhaseChildBlockBackgrounds;
178     paint(paintInfo, paintOffset);
179     paintInfo.phase = PaintPhaseFloat;
180     paint(paintInfo, paintOffset);
181     paintInfo.phase = PaintPhaseForeground;
182     paint(paintInfo, paintOffset);
183     paintInfo.phase = PaintPhaseOutline;
184     paint(paintInfo, paintOffset);
185 }
186
187 RenderObject* RenderScrollbarPart::rendererOwningScrollbar() const
188 {
189     if (!m_scrollbar)
190         return 0;
191     return m_scrollbar->owningRenderer();
192 }
193
194 }