1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/views/controls/glow_hover_controller.h" 6 7 #include "third_party/skia/include/effects/SkGradientShader.h" 8 #include "ui/gfx/canvas.h" 9 #include "ui/gfx/image/image_skia.h" 10 #include "ui/gfx/image/image_skia_operations.h" 11 #include "ui/views/view.h" 12 13 namespace views { 14 15 // Amount to scale the opacity. 16 static const double kTrackOpacityScale = 0.5; 17 static const double kHighlightOpacityScale = 1.0; 18 19 // How long the hover state takes. 20 static const int kTrackHoverDurationMs = 400; 21 22 GlowHoverController::GlowHoverController(views::View* view) 23 : view_(view), 24 animation_(this), 25 opacity_scale_(kTrackOpacityScale) { 26 animation_.set_delegate(this); 27 } 28 29 GlowHoverController::~GlowHoverController() { 30 } 31 32 void GlowHoverController::SetAnimationContainer( 33 gfx::AnimationContainer* container) { 34 animation_.SetContainer(container); 35 } 36 37 void GlowHoverController::SetLocation(const gfx::Point& location) { 38 location_ = location; 39 if (ShouldDraw()) 40 view_->SchedulePaint(); 41 } 42 43 void GlowHoverController::Show(Style style) { 44 switch (style) { 45 case SUBTLE: 46 opacity_scale_ = kTrackOpacityScale; 47 animation_.SetSlideDuration(kTrackHoverDurationMs); 48 animation_.SetTweenType(gfx::Tween::EASE_OUT); 49 animation_.Show(); 50 break; 51 case PRONOUNCED: 52 opacity_scale_ = kHighlightOpacityScale; 53 // Force the end state to show immediately. 54 animation_.Show(); 55 animation_.End(); 56 break; 57 } 58 } 59 60 void GlowHoverController::Hide() { 61 animation_.SetTweenType(gfx::Tween::EASE_IN); 62 animation_.Hide(); 63 } 64 65 void GlowHoverController::HideImmediately() { 66 if (ShouldDraw()) 67 view_->SchedulePaint(); 68 animation_.Reset(); 69 } 70 71 double GlowHoverController::GetAnimationValue() const { 72 return animation_.GetCurrentValue(); 73 } 74 75 bool GlowHoverController::ShouldDraw() const { 76 return animation_.IsShowing() || animation_.is_animating(); 77 } 78 79 void GlowHoverController::Draw(gfx::Canvas* canvas, 80 const gfx::ImageSkia& mask_image) const { 81 if (!ShouldDraw()) 82 return; 83 84 // Draw a radial gradient to hover_canvas. 85 gfx::Canvas hover_canvas(gfx::Size(mask_image.width(), mask_image.height()), 86 canvas->image_scale(), 87 false); 88 89 // Draw a radial gradient to hover_canvas. 90 int radius = view_->width() / 3; 91 92 SkPoint center_point; 93 center_point.iset(location_.x(), location_.y()); 94 SkColor colors[2]; 95 int hover_alpha = 96 static_cast<int>(255 * opacity_scale_ * animation_.GetCurrentValue()); 97 colors[0] = SkColorSetARGB(hover_alpha, 255, 255, 255); 98 colors[1] = SkColorSetARGB(0, 255, 255, 255); 99 skia::RefPtr<SkShader> shader = skia::AdoptRef( 100 SkGradientShader::CreateRadial( 101 center_point, SkIntToScalar(radius), colors, NULL, 2, 102 SkShader::kClamp_TileMode)); 103 // Shader can end up null when radius = 0. 104 // If so, this results in default full tab glow behavior. 105 if (shader) { 106 SkPaint paint; 107 paint.setStyle(SkPaint::kFill_Style); 108 paint.setAntiAlias(true); 109 paint.setShader(shader.get()); 110 hover_canvas.DrawRect(gfx::Rect(location_.x() - radius, 111 location_.y() - radius, 112 radius * 2, radius * 2), paint); 113 } 114 gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage( 115 gfx::ImageSkia(hover_canvas.ExtractImageRep()), mask_image); 116 canvas->DrawImageInt(result, (view_->width() - mask_image.width()) / 2, 117 (view_->height() - mask_image.height()) / 2); 118 } 119 120 void GlowHoverController::AnimationEnded(const gfx::Animation* animation) { 121 view_->SchedulePaint(); 122 } 123 124 void GlowHoverController::AnimationProgressed(const gfx::Animation* animation) { 125 view_->SchedulePaint(); 126 } 127 128 } // namespace views 129