OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/notifications/balloon_view_views.h" | 5 #include "chrome/browser/ui/views/notifications/balloon_view_views.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 // Menu commands | 80 // Menu commands |
81 const int kRevokePermissionCommand = 0; | 81 const int kRevokePermissionCommand = 0; |
82 | 82 |
83 // Colors | 83 // Colors |
84 const SkColor kControlBarBackgroundColor = SkColorSetRGB(245, 245, 245); | 84 const SkColor kControlBarBackgroundColor = SkColorSetRGB(245, 245, 245); |
85 const SkColor kControlBarTextColor = SkColorSetRGB(125, 125, 125); | 85 const SkColor kControlBarTextColor = SkColorSetRGB(125, 125, 125); |
86 const SkColor kControlBarSeparatorLineColor = SkColorSetRGB(180, 180, 180); | 86 const SkColor kControlBarSeparatorLineColor = SkColorSetRGB(180, 180, 180); |
87 | 87 |
88 } // namespace | 88 } // namespace |
89 | 89 |
| 90 // static |
| 91 int BalloonView::GetHorizontalMargin() { |
| 92 return kLeftMargin + kRightMargin + kLeftShadowWidth + kRightShadowWidth; |
| 93 } |
| 94 |
90 BalloonViewImpl::BalloonViewImpl(BalloonCollection* collection) | 95 BalloonViewImpl::BalloonViewImpl(BalloonCollection* collection) |
91 : balloon_(NULL), | 96 : balloon_(NULL), |
92 collection_(collection), | 97 collection_(collection), |
93 frame_container_(NULL), | 98 frame_container_(NULL), |
94 html_container_(NULL), | 99 html_container_(NULL), |
95 html_contents_(NULL), | 100 html_contents_(NULL), |
96 method_factory_(this), | 101 method_factory_(this), |
97 close_button_(NULL), | 102 close_button_(NULL), |
98 animation_(NULL), | 103 animation_(NULL), |
99 options_menu_model_(NULL), | 104 options_menu_model_(NULL), |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 options_menu_button_->SetBoundsRect(GetOptionsButtonBounds()); | 205 options_menu_button_->SetBoundsRect(GetOptionsButtonBounds()); |
201 source_label_->SetBoundsRect(GetLabelBounds()); | 206 source_label_->SetBoundsRect(GetLabelBounds()); |
202 } | 207 } |
203 | 208 |
204 void BalloonViewImpl::RepositionToBalloon() { | 209 void BalloonViewImpl::RepositionToBalloon() { |
205 DCHECK(frame_container_); | 210 DCHECK(frame_container_); |
206 DCHECK(html_container_); | 211 DCHECK(html_container_); |
207 DCHECK(balloon_); | 212 DCHECK(balloon_); |
208 | 213 |
209 if (!kAnimateEnabled) { | 214 if (!kAnimateEnabled) { |
210 frame_container_->SetBounds( | 215 frame_container_->SetBounds(GetBoundsForFrameContainer()); |
211 gfx::Rect(balloon_->GetPosition().x(), balloon_->GetPosition().y(), | |
212 GetTotalWidth(), GetTotalHeight())); | |
213 gfx::Rect contents_rect = GetContentsRectangle(); | 216 gfx::Rect contents_rect = GetContentsRectangle(); |
214 html_container_->SetBounds(contents_rect); | 217 html_container_->SetBounds(contents_rect); |
215 html_contents_->SetPreferredSize(contents_rect.size()); | 218 html_contents_->SetPreferredSize(contents_rect.size()); |
216 content::RenderWidgetHostView* view = | 219 content::RenderWidgetHostView* view = |
217 html_contents_->web_contents()->GetRenderWidgetHostView(); | 220 html_contents_->web_contents()->GetRenderWidgetHostView(); |
218 if (view) | 221 if (view) |
219 view->SetSize(contents_rect.size()); | 222 view->SetSize(contents_rect.size()); |
220 return; | 223 return; |
221 } | 224 } |
222 | 225 |
223 anim_frame_end_ = gfx::Rect( | 226 anim_frame_end_ = GetBoundsForFrameContainer(); |
224 balloon_->GetPosition().x(), balloon_->GetPosition().y(), | |
225 GetTotalWidth(), GetTotalHeight()); | |
226 anim_frame_start_ = frame_container_->GetClientAreaBoundsInScreen(); | 227 anim_frame_start_ = frame_container_->GetClientAreaBoundsInScreen(); |
227 animation_.reset(new ui::SlideAnimation(this)); | 228 animation_.reset(new ui::SlideAnimation(this)); |
228 animation_->Show(); | 229 animation_->Show(); |
229 } | 230 } |
230 | 231 |
231 void BalloonViewImpl::Update() { | 232 void BalloonViewImpl::Update() { |
232 DCHECK(html_contents_.get()) << "BalloonView::Update called before Show"; | 233 DCHECK(html_contents_.get()) << "BalloonView::Update called before Show"; |
233 if (!html_contents_->web_contents()) | 234 if (!html_contents_->web_contents()) |
234 return; | 235 return; |
235 html_contents_->web_contents()->GetController().LoadURL( | 236 html_contents_->web_contents()->GetController().LoadURL( |
236 balloon_->notification().content_url(), content::Referrer(), | 237 balloon_->notification().content_url(), content::Referrer(), |
237 content::PAGE_TRANSITION_LINK, std::string()); | 238 content::PAGE_TRANSITION_LINK, std::string()); |
238 } | 239 } |
239 | 240 |
240 void BalloonViewImpl::AnimationProgressed(const ui::Animation* animation) { | 241 void BalloonViewImpl::AnimationProgressed(const ui::Animation* animation) { |
241 DCHECK(animation == animation_.get()); | 242 DCHECK(animation == animation_.get()); |
242 | 243 |
243 // Linear interpolation from start to end position. | 244 // Linear interpolation from start to end position. |
244 double e = animation->GetCurrentValue(); | 245 gfx::Rect frame_position(animation_->CurrentValueBetween( |
245 double s = (1.0 - e); | 246 anim_frame_start_, anim_frame_end_)); |
246 | |
247 gfx::Rect frame_position( | |
248 static_cast<int>(s * anim_frame_start_.x() + | |
249 e * anim_frame_end_.x()), | |
250 static_cast<int>(s * anim_frame_start_.y() + | |
251 e * anim_frame_end_.y()), | |
252 static_cast<int>(s * anim_frame_start_.width() + | |
253 e * anim_frame_end_.width()), | |
254 static_cast<int>(s * anim_frame_start_.height() + | |
255 e * anim_frame_end_.height())); | |
256 frame_container_->SetBounds(frame_position); | 247 frame_container_->SetBounds(frame_position); |
257 | 248 |
258 gfx::Path path; | 249 gfx::Path path; |
259 gfx::Rect contents_rect = GetContentsRectangle(); | 250 gfx::Rect contents_rect = GetContentsRectangle(); |
260 html_container_->SetBounds(contents_rect); | 251 html_container_->SetBounds(contents_rect); |
261 GetContentsMask(contents_rect, &path); | 252 GetContentsMask(contents_rect, &path); |
262 html_container_->SetShape(path.CreateNativeRegion()); | 253 html_container_->SetShape(path.CreateNativeRegion()); |
263 | 254 |
264 html_contents_->SetPreferredSize(contents_rect.size()); | 255 html_contents_->SetPreferredSize(contents_rect.size()); |
265 content::RenderWidgetHostView* view = | 256 content::RenderWidgetHostView* view = |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 // corners using alpha blending (and we may do other alpha blending | 320 // corners using alpha blending (and we may do other alpha blending |
330 // effects). | 321 // effects). |
331 // Unfortunately, layered windows cannot have child windows. (Well, they can | 322 // Unfortunately, layered windows cannot have child windows. (Well, they can |
332 // but the child windows don't render). | 323 // but the child windows don't render). |
333 // | 324 // |
334 // We carefully keep these two windows in sync to present the illusion of | 325 // We carefully keep these two windows in sync to present the illusion of |
335 // one window to the user. | 326 // one window to the user. |
336 // | 327 // |
337 // We don't let the OS manage the RTL layout of these widgets, because | 328 // We don't let the OS manage the RTL layout of these widgets, because |
338 // this code is already taking care of correctly reversing the layout. | 329 // this code is already taking care of correctly reversing the layout. |
339 gfx::Rect contents_rect = GetContentsRectangle(); | |
340 #if defined(OS_CHROMEOS) && defined(USE_AURA) | 330 #if defined(OS_CHROMEOS) && defined(USE_AURA) |
341 html_contents_.reset(new chromeos::BalloonViewHost(balloon)); | 331 html_contents_.reset(new chromeos::BalloonViewHost(balloon)); |
342 #else | 332 #else |
343 html_contents_.reset(new BalloonViewHost(balloon)); | 333 html_contents_.reset(new BalloonViewHost(balloon)); |
344 #endif | 334 #endif |
345 html_contents_->SetPreferredSize(gfx::Size(10000, 10000)); | 335 html_contents_->SetPreferredSize(gfx::Size(10000, 10000)); |
346 if (enable_web_ui_) | 336 if (enable_web_ui_) |
347 html_contents_->EnableWebUI(); | 337 html_contents_->EnableWebUI(); |
348 | 338 |
349 html_container_ = new views::Widget; | 339 html_container_ = new views::Widget; |
350 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); | 340 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); |
351 params.bounds = contents_rect; | |
352 html_container_->Init(params); | 341 html_container_->Init(params); |
353 html_container_->SetContentsView(html_contents_->view()); | 342 html_container_->SetContentsView(html_contents_->view()); |
354 | 343 |
355 gfx::Rect balloon_rect(x(), y(), GetTotalWidth(), GetTotalHeight()); | |
356 frame_container_ = new views::Widget; | 344 frame_container_ = new views::Widget; |
357 params.delegate = this; | 345 params.delegate = this; |
358 params.transparent = true; | 346 params.transparent = true; |
359 params.bounds = balloon_rect; | 347 params.bounds = GetBoundsForFrameContainer(); |
360 frame_container_->Init(params); | 348 frame_container_->Init(params); |
361 frame_container_->SetContentsView(this); | 349 frame_container_->SetContentsView(this); |
362 frame_container_->StackAboveWidget(html_container_); | 350 frame_container_->StackAboveWidget(html_container_); |
363 | 351 |
| 352 // GetContentsRectangle() is calculated relative to |frame_container_|. Make |
| 353 // sure |frame_container_| has bounds before we ask for |
| 354 // GetContentsRectangle(). |
| 355 html_container_->SetBounds(GetContentsRectangle()); |
| 356 |
364 // SetAlwaysOnTop should be called after StackAboveWidget because otherwise | 357 // SetAlwaysOnTop should be called after StackAboveWidget because otherwise |
365 // the top-most flag will be removed. | 358 // the top-most flag will be removed. |
366 html_container_->SetAlwaysOnTop(true); | 359 html_container_->SetAlwaysOnTop(true); |
367 frame_container_->SetAlwaysOnTop(true); | 360 frame_container_->SetAlwaysOnTop(true); |
368 | 361 |
369 close_button_->SetImage(views::CustomButton::BS_NORMAL, | 362 close_button_->SetImage(views::CustomButton::BS_NORMAL, |
370 rb.GetImageSkiaNamed(IDR_TAB_CLOSE)); | 363 rb.GetImageSkiaNamed(IDR_TAB_CLOSE)); |
371 close_button_->SetImage(views::CustomButton::BS_HOT, | 364 close_button_->SetImage(views::CustomButton::BS_HOT, |
372 rb.GetImageSkiaNamed(IDR_TAB_CLOSE_H)); | 365 rb.GetImageSkiaNamed(IDR_TAB_CLOSE_H)); |
373 close_button_->SetImage(views::CustomButton::BS_PUSHED, | 366 close_button_->SetImage(views::CustomButton::BS_PUSHED, |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 path->lineTo(right, bottom); | 449 path->lineTo(right, bottom); |
457 path->lineTo(left, bottom); | 450 path->lineTo(left, bottom); |
458 path->close(); | 451 path->close(); |
459 } | 452 } |
460 | 453 |
461 gfx::Point BalloonViewImpl::GetContentsOffset() const { | 454 gfx::Point BalloonViewImpl::GetContentsOffset() const { |
462 return gfx::Point(kLeftShadowWidth + kLeftMargin, | 455 return gfx::Point(kLeftShadowWidth + kLeftMargin, |
463 kTopShadowWidth + kTopMargin); | 456 kTopShadowWidth + kTopMargin); |
464 } | 457 } |
465 | 458 |
| 459 gfx::Rect BalloonViewImpl::GetBoundsForFrameContainer() const { |
| 460 return gfx::Rect(balloon_->GetPosition().x(), balloon_->GetPosition().y(), |
| 461 GetTotalWidth(), GetTotalHeight()); |
| 462 } |
| 463 |
466 int BalloonViewImpl::GetShelfHeight() const { | 464 int BalloonViewImpl::GetShelfHeight() const { |
467 // TODO(johnnyg): add scaling here. | 465 // TODO(johnnyg): add scaling here. |
468 int max_button_height = std::max(std::max( | 466 int max_button_height = std::max(std::max( |
469 close_button_->GetPreferredSize().height(), | 467 close_button_->GetPreferredSize().height(), |
470 options_menu_button_->GetPreferredSize().height()), | 468 options_menu_button_->GetPreferredSize().height()), |
471 source_label_->GetPreferredSize().height()); | 469 source_label_->GetPreferredSize().height()); |
472 return max_button_height + kShelfMargin * 2; | 470 return max_button_height + kShelfMargin * 2; |
473 } | 471 } |
474 | 472 |
475 int BalloonViewImpl::GetBalloonFrameHeight() const { | 473 int BalloonViewImpl::GetBalloonFrameHeight() const { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 return; | 531 return; |
534 } | 532 } |
535 | 533 |
536 // If the renderer process attached to this balloon is disconnected | 534 // If the renderer process attached to this balloon is disconnected |
537 // (e.g., because of a crash), we want to close the balloon. | 535 // (e.g., because of a crash), we want to close the balloon. |
538 notification_registrar_.Remove( | 536 notification_registrar_.Remove( |
539 this, chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED, | 537 this, chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED, |
540 content::Source<Balloon>(balloon_)); | 538 content::Source<Balloon>(balloon_)); |
541 Close(false); | 539 Close(false); |
542 } | 540 } |
OLD | NEW |