Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: chrome_frame/infobar_window.cc

Issue 4766003: Preview CL for adding an Infobar facility to Google Chrome Frame.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 // Implementation of the manager for infobar windows.
6
7 #include "chrome_frame/infobar_window.h"
8
9 #include "base/logging.h"
10 #include "base/scoped_ptr.h"
11
12 namespace {
13
14 const UINT_PTR kInfobarSlidingTimerId = 1U;
15 // In milliseconds.
16 const UINT kInfobarSlidingTimerInterval = 50U;
grt (UTC plus 2) 2010/11/10 17:59:29 Consider putting "ms" in the constant name so that
erikwright (departed) 2010/11/24 06:24:56 Agreed.
17 // The step when the infobar is sliding, in pixels.
18 const int kInfobarSlidingStep = 1;
19 // The default height of the infobar.
20 const int kInfobarDefaultHeight = 39;
21
22 } // namespace
23
24 InfobarWindow::InfobarWindow(InfobarType type, InfobarHost* host)
25 : type_(type),
grt (UTC plus 2) 2010/11/10 17:59:29 Although I like spreading the initializer list out
erikwright (departed) 2010/11/24 06:24:56 It does prefer to avoid unnecessary whitespace, bu
26 host_(host),
27 show_(false),
28 target_height_(1),
29 initial_height_(1),
30 content_(NULL),
31 frame_impl_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
32 DCHECK(host_);
33 }
34
35 InfobarWindow::~InfobarWindow() {
36 Reset();
37
38 if (IsWindow()) {
39 DestroyWindow();
40 }
41 }
42
43 HRESULT InfobarWindow::Show(InfobarContent *content,
44 int max_height) {
45 if (content_) {
46 content_->Reset();
47 content_ = NULL;
48 }
49
50 // Create the window if not created.
51 if (!IsWindow()) {
52 Create(host_->GetContainerWindow());
53 RECT dimensions = {0, 0, 0, 0};
54 GetClientRect(&dimensions);
55 dimensions.bottom = 1;
56 MoveWindow(&dimensions, TRUE);
57 }
58 if (!IsWindow())
59 return E_UNEXPECTED;
60
61 HRESULT hr = content->InstallInFrame(&frame_impl_);
62 if (FAILED(hr)) {
63 return hr;
64 }
65
66 StartUpdatingLayout(true, max_height, true);
67
68 // We only keep the pointer in case of success. At this point, we promise to
69 // call Reset at some future point on the content.
70 content_ = content;
71 return S_OK;
72 }
73
74 HRESULT InfobarWindow::Hide() {
75 StartUpdatingLayout(false, 0, false);
76
77 return S_OK;
78 }
79
80 void InfobarWindow::ReserveSpace(RECT* rect) {
81 DCHECK(rect);
82 if (rect == NULL || !show_ || !IsWindow())
83 return;
84
85 RECT infobar_rect = *rect;
86
87 int height = CalculateHeight();
88
89 switch (type_) {
90 case TOP_INFOBAR:
91 infobar_rect.bottom = rect->top = std::min(rect->bottom,
92 rect->top + height);
93 break;
94 case BOTTOM_INFOBAR:
95 infobar_rect.top = rect->bottom = std::max(rect->top,
96 rect->bottom - height);
97 break;
98 default:
99 NOTREACHED() << "Unknown InfobarType value.";
100 break;
101 }
102
103
104 MoveWindow(&infobar_rect, TRUE);
105
106 SetWindowPos(HWND_TOP,
107 &infobar_rect,
108 show_ || height != target_height_ ?
109 SWP_SHOWWINDOW : SWP_HIDEWINDOW);
110
111 if (content_ != NULL) {
112 content_->SetDimensions(infobar_rect);
113 }
114
115 if (height == target_height_) {
116 KillTimer(kInfobarSlidingTimerId);
117 if (!show_ && content_) {
118 // Content is responsible for freeing itself.
119 content_->Reset();
120 content_ = NULL;
121 }
122 }
123 }
124
125 void InfobarWindow::StartUpdatingLayout(bool show, int max_height, bool slide) {
126 if (!IsWindow()) {
127 return;
128 }
129
130 show_ = show;
131 if (show) {
132 // TODO(erikwright): ask our widget for its height
133 target_height_ = (max_height == 0 || kInfobarDefaultHeight < max_height) ?
134 kInfobarDefaultHeight : max_height;
135 if (target_height_ <= 0) {
136 target_height_ = 1;
137 }
138 } else {
139 target_height_ = 1;
140 }
141
142 // Trigger an deferred call to ReserveSpace, in which we will do the actual
143 // MoveWindow
144 if (!host_->UpdateLayout()) {
145 // Failed to trigger a layout - seems our environment is going away or gone.
146 // Let's get out of here.
147 RECT empty = {0, 0, 0, 0};
148 MoveWindow(&empty, TRUE);
149 KillTimer(kInfobarSlidingTimerId);
150 if (content_) {
151 // Content is responsible for freeing itself.
152 content_->Reset();
153 content_ = NULL;
154 }
155 return;
156 }
157
158 if (!slide || !show) {
159 slide_start_ = base::Time();
160 KillTimer(kInfobarSlidingTimerId);
161 } else {
162 RECT dimensions = {0, 0, 0, 0};
163 GetClientRect(&dimensions);
164 slide_start_ = base::Time::Now();
165 initial_height_ = dimensions.bottom;
166 SetTimer(kInfobarSlidingTimerId, kInfobarSlidingTimerInterval, NULL);
167 }
168
169 }
170
171 int InfobarWindow::CalculateHeight() {
172 RECT dimensions;
173 int current_height = GetClientRect(&dimensions) ? dimensions.bottom : 0;
174
175 if (slide_start_.is_null()) {
176 return target_height_;
177 }
178
179 base::TimeDelta elapsed = base::Time::Now() - slide_start_;
180 int travel = (static_cast<int>(elapsed.InMilliseconds()) /
181 kInfobarSlidingTimerInterval) * kInfobarSlidingStep;
182
183 if (current_height < target_height_) {
184 return std::min(current_height + travel, target_height_);
185 } else if (current_height > target_height_) {
186 return std::max(current_height - travel, target_height_);
187 } else {
188 return current_height;
189 }
190 }
191
192 LRESULT InfobarWindow::OnTimer(UINT_PTR nIDEvent) {
193 DCHECK(nIDEvent == kInfobarSlidingTimerId);
194
195 host_->UpdateLayout();
196 return S_OK;
197 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698