blob: 0eeffc9295124d04d2e377b930f45b13873b5bff [file] [log] [blame] [edit]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/renderer/webview_animating_overlay.h"
#include "base/logging.h"
#include "content/public/renderer/render_view.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "ui/gfx/size.h"
#include "ui/gfx/skia_util.h"
const int kAnimationDurationMiliseconds = 500;
const int kAnimationFrameRate = 60;
const int kTargetAlpha = 191;
WebViewAnimatingOverlay::WebViewAnimatingOverlay(
content::RenderView* render_view)
: render_view_(render_view),
state_(HIDDEN),
animation_(kAnimationDurationMiliseconds, kAnimationFrameRate, this) {
}
WebViewAnimatingOverlay::~WebViewAnimatingOverlay() {
if (render_view_->GetWebView())
render_view_->GetWebView()->removePageOverlay(this);
}
void WebViewAnimatingOverlay::Show() {
if (state_ == ANIMATING_IN || state_ == VISIBLE)
return;
if (state_ == ANIMATING_OUT) {
animation_.SetCurrentValue(1.0 - animation_.GetCurrentValue());
} else {
DCHECK_EQ(HIDDEN, state_);
if (render_view_->GetWebView())
render_view_->GetWebView()->addPageOverlay(this, 0);
}
state_ = ANIMATING_IN;
animation_.Start();
}
void WebViewAnimatingOverlay::Hide() {
if (state_ == ANIMATING_OUT || state_ == HIDDEN)
return;
if (state_ == ANIMATING_IN)
animation_.SetCurrentValue(1.0 - animation_.GetCurrentValue());
state_ = ANIMATING_OUT;
animation_.Start();
}
void WebViewAnimatingOverlay::paintPageOverlay(WebKit::WebCanvas* canvas) {
SkRect rect = gfx::RectToSkRect(gfx::Rect(render_view_->GetSize()));
// The center of the radial gradient should be near the top middle.
SkPoint center_point;
center_point.iset(rect.width() * 0.5, rect.height() * 0.05);
int radius = static_cast<int>(rect.width());
// Animate in or out using the alpha.
int alpha = GetCurrentAlpha();
SkColor colors[] = {
SkColorSetARGB(alpha, 255, 255, 255),
SkColorSetARGB(alpha, 127, 127, 127)
};
SkAutoTUnref<SkShader> shader(SkGradientShader::CreateRadial(center_point,
SkIntToScalar(radius), colors, NULL, arraysize(colors),
SkShader::kClamp_TileMode));
SkPaint paint;
paint.setShader(shader);
paint.setDither(true);
canvas->drawRect(rect, paint);
}
void WebViewAnimatingOverlay::AnimationEnded(const ui::Animation* animation) {
if (state_ == ANIMATING_IN) {
state_ = VISIBLE;
} else {
DCHECK_EQ(ANIMATING_OUT, state_);
state_ = HIDDEN;
if (render_view_->GetWebView())
render_view_->GetWebView()->removePageOverlay(this);
}
}
void WebViewAnimatingOverlay::AnimationProgressed(
const ui::Animation* animation) {
render_view_->Repaint(render_view_->GetSize());
}
int WebViewAnimatingOverlay::GetCurrentAlpha() {
switch (state_) {
case ANIMATING_IN:
return animation_.CurrentValueBetween(0, kTargetAlpha);
case ANIMATING_OUT:
return animation_.CurrentValueBetween(kTargetAlpha, 0);
case VISIBLE:
case HIDDEN:
return kTargetAlpha;
}
NOTREACHED();
return 1.0;
}