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