Home | History | Annotate | Download | only in WebPage
      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