Replace WTF::move with WTFMove
[WebKit-https.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 #include <wtf/StackStats.h>
34
35 namespace WebCore {
36
37 RenderScrollbarPart::RenderScrollbarPart(Document& document, Ref<RenderStyle>&& style, RenderScrollbar* scrollbar, ScrollbarPart part)
38     : RenderBlock(document, WTFMove(style), 0)
39     , m_scrollbar(scrollbar)
40     , m_part(part)
41 {
42 }
43
44 RenderScrollbarPart::~RenderScrollbarPart()
45 {
46 }
47
48 void RenderScrollbarPart::layout()
49 {
50     StackStats::LayoutCheckPoint layoutCheckPoint;
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     clearNeedsLayout();
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)
83 {
84     if (!length.isIntrinsicOrAuto() || (sizeType == MinSize && length.isAuto()))
85         return minimumValueForLength(length, containingLength);
86     return ScrollbarTheme::theme().scrollbarThickness();
87 }
88
89 void RenderScrollbarPart::computeScrollbarWidth()
90 {
91     if (!m_scrollbar->owningRenderer())
92         return;
93     // FIXME: We are querying layout information but nothing guarantees that it's up-to-date, especially since we are called at style change.
94     // FIXME: Querying the style's border information doesn't work on table cells with collapsing borders.
95     int visibleSize = m_scrollbar->owningRenderer()->width() - m_scrollbar->owningRenderer()->style().borderLeftWidth() - m_scrollbar->owningRenderer()->style().borderRightWidth();
96     int w = calcScrollbarThicknessUsing(MainOrPreferredSize, style().width(), visibleSize);
97     int minWidth = calcScrollbarThicknessUsing(MinSize, style().minWidth(), visibleSize);
98     int maxWidth = style().maxWidth().isUndefined() ? w : calcScrollbarThicknessUsing(MaxSize, style().maxWidth(), visibleSize);
99     setWidth(std::max(minWidth, std::min(maxWidth, w)));
100     
101     // Buttons and track pieces can all have margins along the axis of the scrollbar. 
102     m_marginBox.setLeft(minimumValueForLength(style().marginLeft(), visibleSize));
103     m_marginBox.setRight(minimumValueForLength(style().marginRight(), visibleSize));
104 }
105
106 void RenderScrollbarPart::computeScrollbarHeight()
107 {
108     if (!m_scrollbar->owningRenderer())
109         return;
110     // FIXME: We are querying layout information but nothing guarantees that it's up-to-date, especially since we are called at style change.
111     // FIXME: Querying the style's border information doesn't work on table cells with collapsing borders.
112     int visibleSize = m_scrollbar->owningRenderer()->height() -  m_scrollbar->owningRenderer()->style().borderTopWidth() - m_scrollbar->owningRenderer()->style().borderBottomWidth();
113     int h = calcScrollbarThicknessUsing(MainOrPreferredSize, style().height(), visibleSize);
114     int minHeight = calcScrollbarThicknessUsing(MinSize, style().minHeight(), visibleSize);
115     int maxHeight = style().maxHeight().isUndefined() ? h : calcScrollbarThicknessUsing(MaxSize, style().maxHeight(), visibleSize);
116     setHeight(std::max(minHeight, std::min(maxHeight, h)));
117
118     // Buttons and track pieces can all have margins along the axis of the scrollbar. 
119     m_marginBox.setTop(minimumValueForLength(style().marginTop(), visibleSize));
120     m_marginBox.setBottom(minimumValueForLength(style().marginBottom(), visibleSize));
121 }
122
123 void RenderScrollbarPart::computePreferredLogicalWidths()
124 {
125     if (!preferredLogicalWidthsDirty())
126         return;
127     
128     m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = 0;
129
130     setPreferredLogicalWidthsDirty(false);
131 }
132
133 void RenderScrollbarPart::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
134 {
135     RenderBlock::styleDidChange(diff, oldStyle);
136     setInline(false);
137     clearPositionedState();
138     setFloating(false);
139     setHasOverflowClip(false);
140     if (oldStyle && m_scrollbar && m_part != NoPart && diff >= StyleDifferenceRepaint)
141         m_scrollbar->theme().invalidatePart(*m_scrollbar, m_part);
142 }
143
144 void RenderScrollbarPart::imageChanged(WrappedImagePtr image, const IntRect* rect)
145 {
146     if (m_scrollbar && m_part != NoPart)
147         m_scrollbar->theme().invalidatePart(*m_scrollbar, m_part);
148     else {
149         if (view().frameView().isFrameViewScrollCorner(*this)) {
150             view().frameView().invalidateScrollCorner(view().frameView().scrollCornerRect());
151             return;
152         }
153         
154         RenderBlock::imageChanged(image, rect);
155     }
156 }
157
158 void RenderScrollbarPart::paintIntoRect(GraphicsContext& graphicsContext, const LayoutPoint& paintOffset, const LayoutRect& rect)
159 {
160     // Make sure our dimensions match the rect.
161     setLocation(rect.location() - toLayoutSize(paintOffset));
162     setWidth(rect.width());
163     setHeight(rect.height());
164
165     if (graphicsContext.paintingDisabled() || !style().opacity())
166         return;
167
168     // We don't use RenderLayers for scrollbar parts, so we need to handle opacity here.
169     // Opacity for ScrollbarBGPart is handled by RenderScrollbarTheme::willPaintScrollbar().
170     bool needsTransparencyLayer = m_part != ScrollbarBGPart && style().opacity() < 1;
171     if (needsTransparencyLayer) {
172         graphicsContext.save();
173         graphicsContext.clip(rect);
174         graphicsContext.beginTransparencyLayer(style().opacity());
175     }
176     
177     // Now do the paint.
178     PaintInfo paintInfo(graphicsContext, snappedIntRect(rect), PaintPhaseBlockBackground, PaintBehaviorNormal);
179     paint(paintInfo, paintOffset);
180     paintInfo.phase = PaintPhaseChildBlockBackgrounds;
181     paint(paintInfo, paintOffset);
182     paintInfo.phase = PaintPhaseFloat;
183     paint(paintInfo, paintOffset);
184     paintInfo.phase = PaintPhaseForeground;
185     paint(paintInfo, paintOffset);
186     paintInfo.phase = PaintPhaseOutline;
187     paint(paintInfo, paintOffset);
188
189     if (needsTransparencyLayer) {
190         graphicsContext.endTransparencyLayer();
191         graphicsContext.restore();
192     }
193 }
194
195 RenderBox* RenderScrollbarPart::rendererOwningScrollbar() const
196 {
197     if (!m_scrollbar)
198         return nullptr;
199     return m_scrollbar->owningRenderer();
200 }
201
202 }