| 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 |