1// Copyright 2014 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/folder_background_view.h"
6
7#include "ui/app_list/app_list_constants.h"
8#include "ui/app_list/views/app_list_folder_view.h"
9#include "ui/app_list/views/apps_container_view.h"
10#include "ui/compositor/scoped_layer_animation_settings.h"
11#include "ui/gfx/canvas.h"
12#include "ui/gfx/transform_util.h"
13
14namespace app_list {
15
16namespace {
17
18const float kFolderInkBubbleScale = 1.2f;
19const int kBubbleTransitionDurationMs = 200;
20
21}  // namespace
22
23FolderBackgroundView::FolderBackgroundView()
24    : folder_view_(NULL),
25      show_state_(NO_BUBBLE) {
26  SetPaintToLayer(true);
27  SetFillsBoundsOpaquely(false);
28}
29
30FolderBackgroundView::~FolderBackgroundView() {
31}
32
33void FolderBackgroundView::UpdateFolderContainerBubble(ShowState state) {
34  if (show_state_ == state ||
35      (state == HIDE_BUBBLE && show_state_ == NO_BUBBLE)) {
36    return;
37  }
38
39  show_state_ = state;
40
41  // Set the initial state before the animation starts.
42  const gfx::Rect bounds(layer()->bounds().size());
43  gfx::Transform transform =
44      gfx::GetScaleTransform(bounds.CenterPoint(), kFolderInkBubbleScale);
45  if (show_state_ == SHOW_BUBBLE) {
46    layer()->SetOpacity(0.0f);
47    layer()->SetTransform(transform);
48  } else {
49    layer()->SetOpacity(1.0f);
50    layer()->SetTransform(gfx::Transform());
51  }
52
53  ui::ScopedLayerAnimationSettings settings(layer()->GetAnimator());
54  settings.AddObserver(this);
55  settings.SetTransitionDuration(
56      base::TimeDelta::FromMilliseconds((kBubbleTransitionDurationMs)));
57  if (show_state_ == SHOW_BUBBLE) {
58    settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN);
59    layer()->SetOpacity(1.0f);
60    layer()->SetTransform(gfx::Transform());
61  } else {
62    settings.SetTweenType(gfx::Tween::FAST_OUT_LINEAR_IN);
63    layer()->SetOpacity(0.0f);
64    layer()->SetTransform(transform);
65  }
66
67  SchedulePaint();
68}
69
70int FolderBackgroundView::GetFolderContainerBubbleRadius() const {
71  return std::max(GetContentsBounds().width(), GetContentsBounds().height()) /
72         2;
73}
74
75void FolderBackgroundView::OnPaint(gfx::Canvas* canvas) {
76  if (show_state_ == NO_BUBBLE)
77    return;
78
79  // Draw ink bubble that shows the folder boundary.
80  SkPaint paint;
81  paint.setStyle(SkPaint::kFill_Style);
82  paint.setAntiAlias(true);
83  paint.setColor(kFolderBubbleColor);
84  canvas->DrawCircle(GetContentsBounds().CenterPoint(),
85                     GetFolderContainerBubbleRadius(),
86                     paint);
87}
88
89void FolderBackgroundView::OnImplicitAnimationsCompleted() {
90  // Show folder name after the ink bubble disappears.
91  if (show_state_ == HIDE_BUBBLE) {
92    static_cast<AppsContainerView*>(parent())->app_list_folder_view()->
93        UpdateFolderNameVisibility(true);
94  }
95}
96
97}  // namespace app_list
98