• 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/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 
RenderScrollbarPart(RenderScrollbar * scrollbar,ScrollbarPart part)37 RenderScrollbarPart::RenderScrollbarPart(RenderScrollbar* scrollbar, ScrollbarPart part)
38     : RenderBlock(0)
39     , m_scrollbar(scrollbar)
40     , m_part(part)
41 {
42 }
43 
~RenderScrollbarPart()44 RenderScrollbarPart::~RenderScrollbarPart()
45 {
46 }
47 
createAnonymous(Document * document,RenderScrollbar * scrollbar,ScrollbarPart part)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 
layout()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 
layoutHorizontalPart()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 
layoutVerticalPart()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 
calcScrollbarThicknessUsing(SizeType sizeType,const Length & length,int containingLength)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 
computeScrollbarWidth()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().isMaxSizeNone() ? 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 
computeScrollbarHeight()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().isMaxSizeNone() ? 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 
computePreferredLogicalWidths()129 void RenderScrollbarPart::computePreferredLogicalWidths()
130 {
131     if (!preferredLogicalWidthsDirty())
132         return;
133 
134     m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = 0;
135 
136     clearPreferredLogicalWidthsDirty();
137 }
138 
styleWillChange(StyleDifference diff,const RenderStyle & newStyle)139 void RenderScrollbarPart::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
140 {
141     RenderBlock::styleWillChange(diff, newStyle);
142     setInline(false);
143 }
144 
styleDidChange(StyleDifference diff,const RenderStyle * oldStyle)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 
imageChanged(WrappedImagePtr image,const IntRect * rect)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 
paintIntoRect(GraphicsContext * graphicsContext,const LayoutPoint & paintOffset,const LayoutRect & rect)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 
rendererOwningScrollbar() const192 RenderObject* RenderScrollbarPart::rendererOwningScrollbar() const
193 {
194     if (!m_scrollbar)
195         return 0;
196     return m_scrollbar->owningRenderer();
197 }
198 
199 }
200