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