Home | History | Annotate | Download | only in views
      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/app_list/views/pulsing_block_view.h"
      6 
      7 #include <vector>
      8 
      9 #include "base/rand_util.h"
     10 #include "third_party/skia/include/core/SkColor.h"
     11 #include "ui/compositor/layer.h"
     12 #include "ui/compositor/layer_animation_element.h"
     13 #include "ui/compositor/layer_animation_sequence.h"
     14 #include "ui/compositor/layer_animator.h"
     15 #include "ui/gfx/canvas.h"
     16 #include "ui/gfx/transform_util.h"
     17 
     18 namespace {
     19 
     20 const SkColor kBlockColor = SkColorSetRGB(225, 225, 225);
     21 const int kBlockSize = 64;
     22 
     23 const int kAnimationDurationInMs = 600;
     24 const float kAnimationOpacity[] = { 0.4f, 0.8f, 0.4f };
     25 const float kAnimationScale[] = { 0.8f, 1.0f, 0.8f };
     26 
     27 void SchedulePulsingAnimation(ui::Layer* layer) {
     28   DCHECK(layer);
     29   DCHECK_EQ(arraysize(kAnimationOpacity), arraysize(kAnimationScale));
     30 
     31   scoped_ptr<ui::LayerAnimationSequence> opacity_sequence(
     32       new ui::LayerAnimationSequence());
     33   scoped_ptr<ui::LayerAnimationSequence> transform_sequence(
     34       new ui::LayerAnimationSequence());
     35 
     36   // The animations loop infinitely.
     37   opacity_sequence->set_is_cyclic(true);
     38   transform_sequence->set_is_cyclic(true);
     39 
     40   const gfx::Rect local_bounds(layer->bounds().size());
     41   for (size_t i = 0; i < arraysize(kAnimationOpacity); ++i) {
     42     opacity_sequence->AddElement(
     43         ui::LayerAnimationElement::CreateOpacityElement(
     44             kAnimationOpacity[i],
     45             base::TimeDelta::FromMilliseconds(kAnimationDurationInMs)));
     46     transform_sequence->AddElement(
     47         ui::LayerAnimationElement::CreateTransformElement(
     48             gfx::GetScaleTransform(local_bounds.CenterPoint(),
     49                                    kAnimationScale[i]),
     50             base::TimeDelta::FromMilliseconds(kAnimationDurationInMs)));
     51   }
     52 
     53   opacity_sequence->AddElement(
     54       ui::LayerAnimationElement::CreatePauseElement(
     55           ui::LayerAnimationElement::OPACITY,
     56           base::TimeDelta::FromMilliseconds(kAnimationDurationInMs)));
     57 
     58   transform_sequence->AddElement(
     59       ui::LayerAnimationElement::CreatePauseElement(
     60           ui::LayerAnimationElement::TRANSFORM,
     61           base::TimeDelta::FromMilliseconds(kAnimationDurationInMs)));
     62 
     63   std::vector<ui::LayerAnimationSequence*> animations;
     64   animations.push_back(opacity_sequence.release());
     65   animations.push_back(transform_sequence.release());
     66   layer->GetAnimator()->ScheduleTogether(animations);
     67 }
     68 
     69 }  // namespace
     70 
     71 namespace app_list {
     72 
     73 PulsingBlockView::PulsingBlockView(const gfx::Size& size, bool start_delay) {
     74   SetPaintToLayer(true);
     75   SetFillsBoundsOpaquely(false);
     76 
     77   const int max_delay = kAnimationDurationInMs * arraysize(kAnimationOpacity);
     78   const int delay = start_delay ? base::RandInt(0, max_delay) : 0;
     79   start_delay_timer_.Start(
     80       FROM_HERE,
     81       base::TimeDelta::FromMilliseconds(delay),
     82       this, &PulsingBlockView::OnStartDelayTimer);
     83 }
     84 
     85 PulsingBlockView::~PulsingBlockView() {
     86 }
     87 
     88 void PulsingBlockView::OnStartDelayTimer() {
     89   SchedulePulsingAnimation(layer());
     90 }
     91 
     92 void PulsingBlockView::OnPaint(gfx::Canvas* canvas) {
     93   gfx::Rect rect(GetContentsBounds());
     94   rect.ClampToCenteredSize(gfx::Size(kBlockSize, kBlockSize));
     95   canvas->FillRect(rect, kBlockColor);
     96 }
     97 
     98 }  // namespace app_list
     99