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