2 * Copyright (C) 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
27 #include "PageOverlay.h"
30 #include "WebProcess.h"
31 #include <WebCore/FrameView.h>
32 #include <WebCore/GraphicsContext.h>
33 #include <WebCore/MainFrame.h>
34 #include <WebCore/Page.h>
35 #include <WebCore/ScrollbarTheme.h>
36 #include <wtf/CurrentTime.h>
38 using namespace WebCore;
42 static const double fadeAnimationDuration = 0.2;
43 static const double fadeAnimationFrameRate = 30;
45 PassRefPtr<PageOverlay> PageOverlay::create(Client* client, OverlayType overlayType)
47 return adoptRef(new PageOverlay(client, overlayType));
50 PageOverlay::PageOverlay(Client* client, OverlayType overlayType)
53 , m_fadeAnimationTimer(RunLoop::main(), this, &PageOverlay::fadeAnimationTimerFired)
54 , m_fadeAnimationStartTime(0)
55 , m_fadeAnimationDuration(fadeAnimationDuration)
56 , m_fadeAnimationType(NoAnimation)
57 , m_fractionFadedIn(1)
58 , m_overlayType(overlayType)
59 , m_backgroundColor(Color::transparent)
63 PageOverlay::~PageOverlay()
67 IntRect PageOverlay::bounds() const
69 if (!m_overrideFrame.isEmpty())
70 return IntRect(IntPoint(), m_overrideFrame.size());
72 FrameView* frameView = m_webPage->mainFrameView();
74 switch (m_overlayType) {
75 case OverlayType::View: {
76 int width = frameView->width();
77 int height = frameView->height();
79 if (!ScrollbarTheme::theme()->usesOverlayScrollbars()) {
80 if (frameView->verticalScrollbar())
81 width -= frameView->verticalScrollbar()->width();
82 if (frameView->horizontalScrollbar())
83 height -= frameView->horizontalScrollbar()->height();
85 return IntRect(0, 0, width, height);
87 case OverlayType::Document:
88 return IntRect(IntPoint(), frameView->contentsSize());
92 return IntRect(IntPoint(), frameView->contentsSize());
95 IntRect PageOverlay::frame() const
97 if (!m_overrideFrame.isEmpty())
98 return m_overrideFrame;
103 void PageOverlay::setFrame(IntRect frame)
105 if (m_overrideFrame == frame)
108 m_overrideFrame = frame;
111 m_webPage->pageOverlayController().didChangeOverlayFrame(*this);
114 void PageOverlay::setBackgroundColor(RGBA32 backgroundColor)
116 if (m_backgroundColor == backgroundColor)
119 m_backgroundColor = backgroundColor;
122 m_webPage->pageOverlayController().didChangeOverlayBackgroundColor(*this);
125 void PageOverlay::setPage(WebPage* webPage)
127 m_client->willMoveToWebPage(this, webPage);
129 m_client->didMoveToWebPage(this, webPage);
131 m_fadeAnimationTimer.stop();
134 void PageOverlay::setNeedsDisplay(const IntRect& dirtyRect)
139 m_webPage->pageOverlayController().setPageOverlayOpacity(*this, m_fractionFadedIn);
140 m_webPage->pageOverlayController().setPageOverlayNeedsDisplay(*this, dirtyRect);
143 void PageOverlay::setNeedsDisplay()
145 setNeedsDisplay(bounds());
148 void PageOverlay::drawRect(GraphicsContext& graphicsContext, const IntRect& dirtyRect)
150 // If the dirty rect is outside the bounds, ignore it.
151 IntRect paintRect = intersection(dirtyRect, bounds());
152 if (paintRect.isEmpty())
155 GraphicsContextStateSaver stateSaver(graphicsContext);
156 m_client->drawRect(this, graphicsContext, paintRect);
159 bool PageOverlay::mouseEvent(const WebMouseEvent& mouseEvent)
161 IntPoint mousePositionInOverlayCoordinates(mouseEvent.position());
163 if (m_overlayType == PageOverlay::OverlayType::Document)
164 mousePositionInOverlayCoordinates = m_webPage->corePage()->mainFrame().view()->rootViewToContents(mousePositionInOverlayCoordinates);
166 // Ignore events outside the bounds.
167 if (!bounds().contains(mousePositionInOverlayCoordinates))
170 return m_client->mouseEvent(this, mouseEvent);
173 void PageOverlay::didScrollFrame(Frame* frame)
175 m_client->didScrollFrame(this, frame);
178 WKTypeRef PageOverlay::copyAccessibilityAttributeValue(WKStringRef attribute, WKTypeRef parameter)
180 return m_client->copyAccessibilityAttributeValue(this, attribute, parameter);
183 WKArrayRef PageOverlay::copyAccessibilityAttributeNames(bool parameterizedNames)
185 return m_client->copyAccessibilityAttributeNames(this, parameterizedNames);
188 void PageOverlay::startFadeInAnimation()
190 m_fractionFadedIn = 0;
191 m_fadeAnimationType = FadeInAnimation;
193 startFadeAnimation();
196 void PageOverlay::startFadeOutAnimation()
198 m_fractionFadedIn = 1;
199 m_fadeAnimationType = FadeOutAnimation;
201 startFadeAnimation();
204 void PageOverlay::stopFadeOutAnimation()
206 m_fractionFadedIn = 1.0;
207 m_fadeAnimationTimer.stop();
210 void PageOverlay::startFadeAnimation()
212 m_fadeAnimationStartTime = currentTime();
213 m_fadeAnimationTimer.startRepeating(1 / fadeAnimationFrameRate);
216 void PageOverlay::fadeAnimationTimerFired()
218 float animationProgress = (currentTime() - m_fadeAnimationStartTime) / m_fadeAnimationDuration;
220 if (animationProgress >= 1.0)
221 animationProgress = 1.0;
223 double sine = sin(piOverTwoFloat * animationProgress);
224 float fadeAnimationValue = sine * sine;
226 m_fractionFadedIn = (m_fadeAnimationType == FadeInAnimation) ? fadeAnimationValue : 1 - fadeAnimationValue;
227 m_webPage->pageOverlayController().setPageOverlayOpacity(*this, m_fractionFadedIn);
229 if (animationProgress == 1.0) {
230 m_fadeAnimationTimer.stop();
232 bool wasFadingOut = m_fadeAnimationType == FadeOutAnimation;
233 m_fadeAnimationType = NoAnimation;
235 // If this was a fade out, go ahead and uninstall the page overlay.
237 m_webPage->uninstallPageOverlay(this, PageOverlay::FadeMode::DoNotFade);
241 void PageOverlay::clear()
243 m_webPage->pageOverlayController().clearPageOverlay(*this);
246 WebCore::GraphicsLayer* PageOverlay::layer()
248 return m_webPage->pageOverlayController().layerForOverlay(*this);
251 } // namespace WebKit