1 /* 2 * Copyright (C) 2010 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. 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. 24 */ 25 26 #include "config.h" 27 #include "PageOverlay.h" 28 29 #include "WebPage.h" 30 #include "WebProcess.h" 31 #include <WebCore/Frame.h> 32 #include <WebCore/FrameView.h> 33 #include <WebCore/GraphicsContext.h> 34 #include <WebCore/Page.h> 35 #include <WebCore/ScrollbarTheme.h> 36 37 using namespace WebCore; 38 39 namespace WebKit { 40 41 static const double fadeAnimationDuration = 0.2; 42 static const double fadeAnimationFrameRate = 30; 43 44 PassRefPtr<PageOverlay> PageOverlay::create(Client* client) 45 { 46 return adoptRef(new PageOverlay(client)); 47 } 48 49 PageOverlay::PageOverlay(Client* client) 50 : m_client(client) 51 , m_webPage(0) 52 , m_fadeAnimationTimer(WebProcess::shared().runLoop(), this, &PageOverlay::fadeAnimationTimerFired) 53 , m_fadeAnimationStartTime(0.0) 54 , m_fadeAnimationDuration(fadeAnimationDuration) 55 , m_fadeAnimationType(NoAnimation) 56 , m_fractionFadedIn(1.0) 57 { 58 } 59 60 PageOverlay::~PageOverlay() 61 { 62 } 63 64 IntRect PageOverlay::bounds() const 65 { 66 FrameView* frameView = m_webPage->corePage()->mainFrame()->view(); 67 68 int width = frameView->width(); 69 int height = frameView->height(); 70 71 if (!ScrollbarTheme::nativeTheme()->usesOverlayScrollbars()) { 72 if (frameView->verticalScrollbar()) 73 width -= frameView->verticalScrollbar()->width(); 74 if (frameView->horizontalScrollbar()) 75 height -= frameView->horizontalScrollbar()->height(); 76 } 77 return IntRect(0, 0, width, height); 78 } 79 80 void PageOverlay::setPage(WebPage* webPage) 81 { 82 m_client->willMoveToWebPage(this, webPage); 83 m_webPage = webPage; 84 m_client->didMoveToWebPage(this, webPage); 85 86 m_fadeAnimationTimer.stop(); 87 } 88 89 void PageOverlay::setNeedsDisplay(const IntRect& dirtyRect) 90 { 91 if (m_webPage) 92 m_webPage->drawingArea()->setPageOverlayNeedsDisplay(dirtyRect); 93 } 94 95 void PageOverlay::setNeedsDisplay() 96 { 97 setNeedsDisplay(bounds()); 98 } 99 100 void PageOverlay::drawRect(GraphicsContext& graphicsContext, const IntRect& dirtyRect) 101 { 102 // If the dirty rect is outside the bounds, ignore it. 103 IntRect paintRect = intersection(dirtyRect, bounds()); 104 if (paintRect.isEmpty()) 105 return; 106 107 graphicsContext.save(); 108 graphicsContext.beginTransparencyLayer(1); 109 graphicsContext.setCompositeOperation(CompositeCopy); 110 111 m_client->drawRect(this, graphicsContext, paintRect); 112 113 graphicsContext.endTransparencyLayer(); 114 graphicsContext.restore(); 115 } 116 117 bool PageOverlay::mouseEvent(const WebMouseEvent& mouseEvent) 118 { 119 // Ignore events outside the bounds. 120 if (!bounds().contains(mouseEvent.position())) 121 return false; 122 123 return m_client->mouseEvent(this, mouseEvent); 124 } 125 126 void PageOverlay::startFadeInAnimation() 127 { 128 m_fractionFadedIn = 0.0; 129 m_fadeAnimationType = FadeInAnimation; 130 131 startFadeAnimation(); 132 } 133 134 void PageOverlay::startFadeOutAnimation() 135 { 136 m_fractionFadedIn = 1.0; 137 m_fadeAnimationType = FadeOutAnimation; 138 139 startFadeAnimation(); 140 } 141 142 void PageOverlay::startFadeAnimation() 143 { 144 m_fadeAnimationStartTime = currentTime(); 145 146 // Start the timer 147 m_fadeAnimationTimer.startRepeating(1 / fadeAnimationFrameRate); 148 } 149 150 void PageOverlay::fadeAnimationTimerFired() 151 { 152 float animationProgress = (currentTime() - m_fadeAnimationStartTime) / m_fadeAnimationDuration; 153 154 if (animationProgress >= 1.0) 155 animationProgress = 1.0; 156 157 double sine = sin(piOverTwoFloat * animationProgress); 158 float fadeAnimationValue = sine * sine; 159 160 m_fractionFadedIn = (m_fadeAnimationType == FadeInAnimation) ? fadeAnimationValue : 1 - fadeAnimationValue; 161 setNeedsDisplay(); 162 163 if (animationProgress == 1.0) { 164 m_fadeAnimationTimer.stop(); 165 166 bool wasFadingOut = m_fadeAnimationType == FadeOutAnimation; 167 m_fadeAnimationType = NoAnimation; 168 169 if (wasFadingOut) { 170 // If this was a fade out, go ahead and uninstall the page overlay. 171 m_webPage->uninstallPageOverlay(this, false); 172 } 173 } 174 } 175 176 } // namespace WebKit 177