OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 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/app_launched_animation.h" | |
6 | |
7 #include "chrome/browser/extensions/image_loading_tracker.h" | |
8 #include "chrome/common/extensions/extension.h" | |
9 #include "chrome/common/extensions/extension_icon_set.h" | |
10 #include "chrome/common/extensions/extension_resource.h" | |
11 #include "gfx/rect.h" | |
12 #include "ui/base/animation/animation.h" | |
13 #include "ui/base/animation/animation_delegate.h" | |
14 #include "ui/base/animation/slide_animation.h" | |
15 #include "views/controls/image_view.h" | |
16 #include "views/widget/widget_win.h" | |
17 | |
18 namespace { | |
19 | |
20 // Start at 1, end at 0 | |
21 // 0ms You click the icon | |
22 // 0ms The launcher and contents begins to fade out, the icon | |
23 // you clicked does not (stays opaque) | |
24 // 0ms The app begins loading behind the launcher | |
25 // +100ms The app icon begins to fade out. | |
26 // +200ms The launcher finishes fading out | |
27 // +350ms The app icon finishes fading out | |
28 | |
29 // How long the fade should take. | |
30 static const int kDurationMS = 250; | |
31 | |
32 // The delay before the fade out should start. | |
33 static const int kDelayMS = 100; | |
34 | |
35 // AppLaunchedAnimation creates an animation. It loads the icon for the | |
36 // extension and once the image is loaded the animation starts. The icon fades | |
37 // out after a short delay. | |
38 class AppLaunchedAnimationWin : public ui::AnimationDelegate, | |
39 public ImageLoadingTracker::Observer, | |
40 public views::ImageView { | |
41 public: | |
42 AppLaunchedAnimationWin(const Extension* extension, const gfx::Rect& rect); | |
43 | |
44 private: | |
45 // ui::AnimationDelegate | |
46 virtual void AnimationProgressed(const ui::Animation* animation); | |
47 virtual void AnimationCanceled(const ui::Animation* animation); | |
48 virtual void AnimationEnded(const ui::Animation* animation); | |
49 | |
50 // We use a HWND for the popup so that it may float above any HWNDs in our UI. | |
51 views::WidgetWin* popup_; | |
52 | |
53 // The rect to use for the popup. | |
54 gfx::Rect rect_; | |
55 | |
56 // Used for loading extension application icon. | |
57 ImageLoadingTracker app_icon_loader_; | |
58 | |
59 // ImageLoadingTracker::Observer. | |
60 virtual void OnImageLoaded(SkBitmap* image, ExtensionResource resource, | |
61 int index); | |
62 | |
63 // Hover animation. | |
64 scoped_ptr<ui::SlideAnimation> animation_; | |
65 | |
66 DISALLOW_COPY_AND_ASSIGN(AppLaunchedAnimationWin); | |
67 }; | |
68 | |
69 AppLaunchedAnimationWin::AppLaunchedAnimationWin(const Extension* extension, | |
70 const gfx::Rect& rect) | |
71 : popup_(NULL), | |
72 rect_(rect), | |
73 ALLOW_THIS_IN_INITIALIZER_LIST(app_icon_loader_(this)) { | |
74 DCHECK(extension); | |
75 app_icon_loader_.LoadImage( | |
76 extension, | |
77 extension->GetIconResource(Extension::EXTENSION_ICON_LARGE, | |
78 ExtensionIconSet::MATCH_EXACTLY), | |
79 rect_.size(), | |
80 ImageLoadingTracker::DONT_CACHE); | |
81 } | |
82 | |
83 void AppLaunchedAnimationWin::AnimationCanceled( | |
84 const ui::Animation* animation) { | |
85 AnimationEnded(animation); | |
86 } | |
87 | |
88 void AppLaunchedAnimationWin::AnimationEnded(const ui::Animation* animation) { | |
89 popup_->Close(); | |
90 } | |
91 | |
92 void AppLaunchedAnimationWin::AnimationProgressed( | |
93 const ui::Animation* animation) { | |
94 // GetCurrentValue goes from 1 to 0 since we are hiding. | |
95 const double current_value = 1.0 - animation->GetCurrentValue(); | |
96 const double current_time = current_value * (kDelayMS + kDurationMS); | |
97 | |
98 double opacity = 1.0 - | |
99 std::max(0.0, static_cast<double>(current_time - kDelayMS)) / | |
100 static_cast<double>(kDurationMS); | |
101 | |
102 popup_->SetOpacity(static_cast<SkColor>(opacity * 255.0)); | |
103 SchedulePaint(); | |
104 } | |
105 | |
106 void AppLaunchedAnimationWin::OnImageLoaded(SkBitmap* image, | |
107 ExtensionResource resource, | |
108 int index) { | |
109 if (image) { | |
110 SetImage(image); | |
111 | |
112 popup_ = new views::WidgetWin; | |
113 popup_->set_window_style(WS_POPUP); | |
114 popup_->set_window_ex_style(WS_EX_LAYERED | WS_EX_TOOLWINDOW | | |
115 WS_EX_TRANSPARENT); | |
116 popup_->SetOpacity(static_cast<SkColor>(255)); | |
117 | |
118 popup_->Init(NULL, rect_); | |
119 popup_->SetContentsView(this); | |
120 popup_->Show(); | |
121 | |
122 // Start animation. | |
123 animation_.reset(new ui::SlideAnimation(this)); | |
124 animation_->SetSlideDuration(kDelayMS + kDurationMS); | |
125 animation_->SetTweenType(ui::Tween::LINEAR); | |
126 animation_->Reset(1.0); | |
127 animation_->Hide(); | |
128 } | |
129 } | |
130 | |
131 } // namespace | |
132 | |
133 // static | |
134 void AppLaunchedAnimation::Show(const Extension* extension, | |
135 const gfx::Rect& rect) { | |
136 // The animation will delete itself when it's finished. | |
137 new AppLaunchedAnimationWin(extension, rect); | |
138 } | |
OLD | NEW |