1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/views/download_started_animation.h"
#include "app/resource_bundle.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/notification_service.h"
#include "chrome/views/widget/widget_win.h"
#include "grit/theme_resources.h"
// How long to spend moving downwards and fading out after waiting.
static const int kMoveTimeMs = 600;
// The animation framerate.
static const int kFrameRateHz = 60;
// What fraction of the frame height to move downward from the frame center.
// Note that setting this greater than 0.5 will mean moving past the bottom of
// the frame.
static const double kMoveFraction = 1.0 / 3.0;
DownloadStartedAnimation::DownloadStartedAnimation(TabContents* tab_contents)
: Animation(kMoveTimeMs, kFrameRateHz, NULL),
popup_(NULL),
tab_contents_(tab_contents) {
static SkBitmap* kDownloadImage = NULL;
if (!kDownloadImage) {
kDownloadImage = ResourceBundle::GetSharedInstance().GetBitmapNamed(
IDR_DOWNLOAD_ANIMATION_BEGIN);
}
// If we're too small to show the download image, then don't bother -
// the shelf will be enough.
tab_contents_->GetContainerBounds(&tab_contents_bounds_);
if (tab_contents_bounds_.height() < kDownloadImage->height())
return;
registrar_.Add(
this,
NotificationType::TAB_CONTENTS_HIDDEN,
Source<TabContents>(tab_contents_));
registrar_.Add(
this,
NotificationType::TAB_CONTENTS_DESTROYED,
Source<TabContents>(tab_contents_));
SetImage(kDownloadImage);
gfx::Rect rc(0, 0, 0, 0);
popup_ = new views::WidgetWin;
popup_->set_window_style(WS_POPUP);
popup_->set_window_ex_style(WS_EX_LAYERED | WS_EX_TOOLWINDOW |
WS_EX_TRANSPARENT);
popup_->SetLayeredAlpha(0x00);
popup_->Init(tab_contents_->GetNativeView(), rc, false);
popup_->SetContentsView(this);
Reposition();
popup_->Show();
Start();
}
void DownloadStartedAnimation::Reposition() {
if (!tab_contents_)
return;
// Align the image with the bottom left of the web contents (so that it
// points to the newly created download).
gfx::Size size = GetPreferredSize();
popup_->MoveWindow(
tab_contents_bounds_.x(),
static_cast<int>(tab_contents_bounds_.bottom() -
size.height() - size.height() * (1 - GetCurrentValue())),
size.width(),
size.height());
}
void DownloadStartedAnimation::Close() {
if (!tab_contents_)
return;
registrar_.Remove(
this,
NotificationType::TAB_CONTENTS_HIDDEN,
Source<TabContents>(tab_contents_));
registrar_.Remove(
this,
NotificationType::TAB_CONTENTS_DESTROYED,
Source<TabContents>(tab_contents_));
tab_contents_ = NULL;
popup_->Close();
}
void DownloadStartedAnimation::AnimateToState(double state) {
if (state >= 1.0) {
Close();
} else {
Reposition();
// Start at zero, peak halfway and end at zero.
double opacity = std::min(1.0 - pow(GetCurrentValue() - 0.5, 2) * 4.0,
static_cast<double>(1.0));
popup_->SetLayeredAlpha(
static_cast<BYTE>(opacity * 255.0));
SchedulePaint(); // Reposition() calls MoveWindow() which never picks up
// alpha changes, so we need to force a paint.
}
}
void DownloadStartedAnimation::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
Close();
}
|