Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / views / download / download_started_animation_views.cc
blob242a6a114c5d04ec32254adcde043a3bd9fcd728
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.
5 #include "chrome/browser/download/download_started_animation.h"
7 #include "content/public/browser/web_contents.h"
8 #include "grit/theme_resources.h"
9 #include "ui/base/resource/resource_bundle.h"
10 #include "ui/gfx/animation/linear_animation.h"
11 #include "ui/gfx/geometry/rect.h"
12 #include "ui/gfx/paint_vector_icon.h"
13 #include "ui/gfx/vector_icons_public.h"
14 #include "ui/native_theme/common_theme.h"
15 #include "ui/native_theme/native_theme.h"
16 #include "ui/views/controls/image_view.h"
17 #include "ui/views/widget/widget.h"
19 // How long to spend moving downwards and fading out after waiting.
20 const int kMoveTimeMs = 600;
22 // The animation framerate.
23 const int kFrameRateHz = 60;
25 namespace {
27 // DownloadStartAnimation creates an animation (which begins running
28 // immediately) that animates an image downward from the center of the frame
29 // provided on the constructor, while simultaneously fading it out. To use,
30 // simply call "new DownloadStartAnimation"; the class cleans itself up when it
31 // finishes animating.
32 class DownloadStartedAnimationViews : public gfx::LinearAnimation,
33 public views::ImageView {
34 public:
35 explicit DownloadStartedAnimationViews(content::WebContents* web_contents);
37 private:
38 // Move the animation to wherever it should currently be.
39 void Reposition();
41 // Shut down the animation cleanly.
42 void Close();
44 // Animation
45 void AnimateToState(double state) override;
47 // We use a TYPE_POPUP for the popup so that it may float above any windows in
48 // our UI.
49 views::Widget* popup_;
51 // The content area at the start of the animation. We store this so that the
52 // download shelf's resizing of the content area doesn't cause the animation
53 // to move around. This means that once started, the animation won't move
54 // with the parent window, but it's so fast that this shouldn't cause too
55 // much heartbreak.
56 gfx::Rect web_contents_bounds_;
58 DISALLOW_COPY_AND_ASSIGN(DownloadStartedAnimationViews);
61 DownloadStartedAnimationViews::DownloadStartedAnimationViews(
62 content::WebContents* web_contents)
63 : gfx::LinearAnimation(kMoveTimeMs, kFrameRateHz, NULL),
64 popup_(NULL) {
65 SkColor blue;
66 CHECK(ui::CommonThemeGetSystemColor(ui::NativeTheme::kColorId_GoogleBlue,
67 &blue));
68 gfx::ImageSkia download_image =
69 gfx::CreateVectorIcon(gfx::VectorIconId::FILE_DOWNLOAD_SHELF, 72, blue);
71 // If we're too small to show the download image, then don't bother -
72 // the shelf will be enough.
73 web_contents_bounds_ = web_contents->GetContainerBounds();
74 if (web_contents_bounds_.height() < download_image.height())
75 return;
77 SetImage(&download_image);
79 popup_ = new views::Widget;
81 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
82 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
83 params.accept_events = false;
84 params.parent = web_contents->GetNativeView();
85 popup_->Init(params);
86 popup_->SetOpacity(0x00);
87 popup_->SetContentsView(this);
88 Reposition();
89 popup_->Show();
91 Start();
94 void DownloadStartedAnimationViews::Reposition() {
95 // Align the image with the bottom left of the web contents (so that it
96 // points to the newly created download).
97 gfx::Size size = GetPreferredSize();
98 int x = base::i18n::IsRTL() ?
99 web_contents_bounds_.right() - size.width() : web_contents_bounds_.x();
100 popup_->SetBounds(gfx::Rect(
102 static_cast<int>(web_contents_bounds_.bottom() -
103 size.height() - size.height() * (1 - GetCurrentValue())),
104 size.width(),
105 size.height()));
108 void DownloadStartedAnimationViews::Close() {
109 popup_->Close();
112 void DownloadStartedAnimationViews::AnimateToState(double state) {
113 if (state >= 1.0) {
114 Close();
115 } else {
116 Reposition();
118 // Start at zero, peak halfway and end at zero.
119 double opacity = std::min(1.0 - pow(GetCurrentValue() - 0.5, 2) * 4.0,
120 static_cast<double>(1.0));
122 popup_->SetOpacity(static_cast<unsigned char>(opacity * 255.0));
126 } // namespace
128 // static
129 void DownloadStartedAnimation::Show(content::WebContents* web_contents) {
130 // The animation will delete itself when it's finished.
131 new DownloadStartedAnimationViews(web_contents);