• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SchedulePulsingAnimation(ui::Layer * layer)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 
PulsingBlockView(const gfx::Size & size,bool start_delay)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 
~PulsingBlockView()85 PulsingBlockView::~PulsingBlockView() {
86 }
87 
OnStartDelayTimer()88 void PulsingBlockView::OnStartDelayTimer() {
89   SchedulePulsingAnimation(layer());
90 }
91 
OnPaint(gfx::Canvas * canvas)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