OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 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 | 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/views/infobars/infobars.h" | 5 #include "chrome/browser/views/infobars/infobars.h" |
6 | 6 |
7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
8 #include "app/resource_bundle.h" | 8 #include "app/resource_bundle.h" |
9 #include "app/slide_animation.h" | 9 #include "app/slide_animation.h" |
10 #if defined(OS_WIN) | 10 #if defined(OS_WIN) |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 void InfoBar::Layout() { | 136 void InfoBar::Layout() { |
137 gfx::Size button_ps = close_button_->GetPreferredSize(); | 137 gfx::Size button_ps = close_button_->GetPreferredSize(); |
138 close_button_->SetBounds(width() - kHorizontalPadding - button_ps.width(), | 138 close_button_->SetBounds(width() - kHorizontalPadding - button_ps.width(), |
139 OffsetY(this, button_ps), button_ps.width(), | 139 OffsetY(this, button_ps), button_ps.width(), |
140 button_ps.height()); | 140 button_ps.height()); |
141 } | 141 } |
142 | 142 |
143 void InfoBar::ViewHierarchyChanged(bool is_add, views::View* parent, | 143 void InfoBar::ViewHierarchyChanged(bool is_add, views::View* parent, |
144 views::View* child) { | 144 views::View* child) { |
145 if (child == this) { | 145 if (child == this) { |
146 if (is_add) { | 146 if (is_add) |
147 InfoBarAdded(); | 147 InfoBarAdded(); |
148 } else { | 148 else |
149 InfoBarRemoved(); | 149 InfoBarRemoved(); |
150 } | |
151 } | 150 } |
152 | 151 |
153 if (GetWidget() && GetWidget()->IsAccessibleWidget()) { | 152 if (GetWidget() && GetWidget()->IsAccessibleWidget()) { |
154 // For accessibility, make the close button the last child view. | 153 // For accessibility, make the close button the last child view. |
155 if (parent == this && child != close_button_ && | 154 if (parent == this && child != close_button_ && |
156 HasChildView(close_button_) && | 155 HasChildView(close_button_) && |
157 GetChildViewAt(GetChildViewCount() - 1) != close_button_) { | 156 GetChildViewAt(GetChildViewCount() - 1) != close_button_) { |
158 RemoveChildView(close_button_); | 157 RemoveChildView(close_button_); |
159 AddChildView(close_button_); | 158 AddChildView(close_button_); |
160 } | 159 } |
(...skipping 20 matching lines...) Expand all Loading... |
181 } | 180 } |
182 | 181 |
183 int InfoBar::OffsetY(views::View* parent, const gfx::Size prefsize) { | 182 int InfoBar::OffsetY(views::View* parent, const gfx::Size prefsize) { |
184 return CenterY(prefsize) - | 183 return CenterY(prefsize) - |
185 (static_cast<int>(target_height_) - parent->height()); | 184 (static_cast<int>(target_height_) - parent->height()); |
186 } | 185 } |
187 | 186 |
188 // InfoBar, views::ButtonListener implementation: ------------------ | 187 // InfoBar, views::ButtonListener implementation: ------------------ |
189 | 188 |
190 void InfoBar::ButtonPressed(views::Button* sender, const views::Event& event) { | 189 void InfoBar::ButtonPressed(views::Button* sender, const views::Event& event) { |
191 if (sender == close_button_) { | 190 if ((sender == close_button_) && delegate_) { |
192 if (delegate_) | 191 delegate_->InfoBarDismissed(); |
193 delegate_->InfoBarDismissed(); | |
194 RemoveInfoBar(); | 192 RemoveInfoBar(); |
195 } | 193 } |
196 } | 194 } |
197 | 195 |
198 // InfoBar, views::FocusChangeListener implementation: ------------------ | 196 // InfoBar, views::FocusChangeListener implementation: ------------------ |
199 | 197 |
200 void InfoBar::FocusWillChange(View* focused_before, View* focused_now) { | 198 void InfoBar::FocusWillChange(View* focused_before, View* focused_now) { |
201 // This will trigger some screen readers to read the entire contents of this | 199 // This will trigger some screen readers to read the entire contents of this |
202 // infobar. | 200 // infobar. |
203 if (focused_before && focused_now && | 201 if (focused_before && focused_now && |
204 !this->IsParentOf(focused_before) && this->IsParentOf(focused_now)) { | 202 !this->IsParentOf(focused_before) && this->IsParentOf(focused_now)) { |
205 NotifyAccessibilityEvent(AccessibilityTypes::EVENT_ALERT); | 203 NotifyAccessibilityEvent(AccessibilityTypes::EVENT_ALERT); |
206 } | 204 } |
207 } | 205 } |
208 | 206 |
209 // InfoBar, AnimationDelegate implementation: ---------------------------------- | 207 // InfoBar, AnimationDelegate implementation: ---------------------------------- |
210 | 208 |
211 void InfoBar::AnimationProgressed(const Animation* animation) { | 209 void InfoBar::AnimationProgressed(const Animation* animation) { |
212 if (container_) | 210 if (container_) |
213 container_->InfoBarAnimated(true); | 211 container_->InfoBarAnimated(true); |
214 } | 212 } |
215 | 213 |
216 void InfoBar::AnimationEnded(const Animation* animation) { | 214 void InfoBar::AnimationEnded(const Animation* animation) { |
217 if (container_) { | 215 if (container_) { |
218 container_->InfoBarAnimated(false); | 216 container_->InfoBarAnimated(false); |
219 | |
220 if (!animation_->IsShowing()) | 217 if (!animation_->IsShowing()) |
221 Close(); | 218 Close(); |
222 } | 219 } |
223 } | 220 } |
224 | 221 |
225 // InfoBar, private: ----------------------------------------------------------- | 222 // InfoBar, private: ----------------------------------------------------------- |
226 | 223 |
227 void InfoBar::AnimateOpen() { | 224 void InfoBar::AnimateOpen() { |
228 animation_->Show(); | 225 animation_->Show(); |
229 } | 226 } |
230 | 227 |
231 void InfoBar::Open() { | 228 void InfoBar::Open() { |
232 // Set the animation value to 1.0 so that GetPreferredSize() returns the right | 229 // Set the animation value to 1.0 so that GetPreferredSize() returns the right |
233 // size. | 230 // size. |
234 animation_->Reset(1.0); | 231 animation_->Reset(1.0); |
235 if (container_) | 232 if (container_) |
236 container_->InfoBarAnimated(false); | 233 container_->InfoBarAnimated(false); |
237 } | 234 } |
238 | 235 |
239 void InfoBar::AnimateClose() { | 236 void InfoBar::AnimateClose() { |
| 237 delegate_ = NULL; |
240 bool restore_focus = true; | 238 bool restore_focus = true; |
241 #if defined(OS_WIN) | 239 #if defined(OS_WIN) |
242 // Do not restore focus (and active state with it) on Windows if some other | 240 // Do not restore focus (and active state with it) on Windows if some other |
243 // top-level window became active. | 241 // top-level window became active. |
244 if (GetWidget() && | 242 if (GetWidget() && |
245 !win_util::DoesWindowBelongToActiveWindow(GetWidget()->GetNativeView())) { | 243 !win_util::DoesWindowBelongToActiveWindow(GetWidget()->GetNativeView())) { |
246 restore_focus = false; | 244 restore_focus = false; |
247 } | 245 } |
248 #endif // defined(OS_WIN) | 246 #endif // defined(OS_WIN) |
249 DestroyFocusTracker(restore_focus); | 247 DestroyFocusTracker(restore_focus); |
250 animation_->Hide(); | 248 animation_->Hide(); |
251 } | 249 } |
252 | 250 |
253 void InfoBar::Close() { | 251 void InfoBar::Close() { |
| 252 delegate_ = NULL; |
254 GetParent()->RemoveChildView(this); | 253 GetParent()->RemoveChildView(this); |
255 // Note that we only tell the delegate we're closed here, and not when we're | |
256 // simply destroyed (by virtue of a tab switch or being moved from window to | |
257 // window), since this action can cause the delegate to destroy itself. | |
258 if (delegate_) { | |
259 delegate_->InfoBarClosed(); | |
260 delegate_ = NULL; | |
261 } | |
262 } | 254 } |
263 | 255 |
264 void InfoBar::InfoBarAdded() { | 256 void InfoBar::InfoBarAdded() { |
265 // The container_ pointer must be set before adding to the view hierarchy. | 257 // The container_ pointer must be set before adding to the view hierarchy. |
266 DCHECK(container_); | 258 DCHECK(container_); |
267 #if defined(OS_WIN) | 259 #if defined(OS_WIN) |
268 // When we're added to a view hierarchy within a widget, we create an | 260 // When we're added to a view hierarchy within a widget, we create an |
269 // external focus tracker to track what was focused in case we obtain | 261 // external focus tracker to track what was focused in case we obtain |
270 // focus so that we can restore focus when we're removed. | 262 // focus so that we can restore focus when we're removed. |
271 views::Widget* widget = GetWidget(); | 263 views::Widget* widget = GetWidget(); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 AddChildView(link_); | 387 AddChildView(link_); |
396 } | 388 } |
397 | 389 |
398 LinkInfoBar::~LinkInfoBar() { | 390 LinkInfoBar::~LinkInfoBar() { |
399 } | 391 } |
400 | 392 |
401 // LinkInfoBar, views::LinkController implementation: -------------------------- | 393 // LinkInfoBar, views::LinkController implementation: -------------------------- |
402 | 394 |
403 void LinkInfoBar::LinkActivated(views::Link* source, int event_flags) { | 395 void LinkInfoBar::LinkActivated(views::Link* source, int event_flags) { |
404 DCHECK(source == link_); | 396 DCHECK(source == link_); |
405 if (GetDelegate()->LinkClicked( | 397 if (delegate() && GetDelegate()->LinkClicked( |
406 event_utils::DispositionFromEventFlags(event_flags))) { | 398 event_utils::DispositionFromEventFlags(event_flags))) |
407 RemoveInfoBar(); | 399 RemoveInfoBar(); |
408 } | |
409 } | 400 } |
410 | 401 |
411 // LinkInfoBar, views::View overrides: ----------------------------------------- | 402 // LinkInfoBar, views::View overrides: ----------------------------------------- |
412 | 403 |
413 void LinkInfoBar::Layout() { | 404 void LinkInfoBar::Layout() { |
414 // Layout the close button. | 405 // Layout the close button. |
415 InfoBar::Layout(); | 406 InfoBar::Layout(); |
416 | 407 |
417 // Layout the icon. | 408 // Layout the icon. |
418 gfx::Size icon_ps = icon_->GetPreferredSize(); | 409 gfx::Size icon_ps = icon_->GetPreferredSize(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 // LinkInfoBar, private: ------------------------------------------------------- | 445 // LinkInfoBar, private: ------------------------------------------------------- |
455 | 446 |
456 LinkInfoBarDelegate* LinkInfoBar::GetDelegate() { | 447 LinkInfoBarDelegate* LinkInfoBar::GetDelegate() { |
457 return delegate()->AsLinkInfoBarDelegate(); | 448 return delegate()->AsLinkInfoBarDelegate(); |
458 } | 449 } |
459 | 450 |
460 // ConfirmInfoBar, public: ----------------------------------------------------- | 451 // ConfirmInfoBar, public: ----------------------------------------------------- |
461 | 452 |
462 ConfirmInfoBar::ConfirmInfoBar(ConfirmInfoBarDelegate* delegate) | 453 ConfirmInfoBar::ConfirmInfoBar(ConfirmInfoBarDelegate* delegate) |
463 : AlertInfoBar(delegate), | 454 : AlertInfoBar(delegate), |
| 455 cached_buttons_(delegate->GetButtons()), |
464 ok_button_(NULL), | 456 ok_button_(NULL), |
465 cancel_button_(NULL), | 457 cancel_button_(NULL), |
466 link_(NULL), | 458 link_(NULL), |
467 initialized_(false) { | 459 initialized_(false) { |
468 ok_button_ = new views::NativeButton(this, | 460 ok_button_ = new views::NativeButton(this, |
469 UTF16ToWideHack(delegate->GetButtonLabel( | 461 UTF16ToWideHack(delegate->GetButtonLabel( |
470 ConfirmInfoBarDelegate::BUTTON_OK))); | 462 ConfirmInfoBarDelegate::BUTTON_OK))); |
471 ok_button_->SetAccessibleName(ok_button_->label()); | 463 ok_button_->SetAccessibleName(ok_button_->label()); |
472 if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK_DEFAULT) | 464 if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK_DEFAULT) |
473 ok_button_->SetAppearsAsDefault(true); | 465 ok_button_->SetAppearsAsDefault(true); |
(...skipping 21 matching lines...) Expand all Loading... |
495 delete link_; | 487 delete link_; |
496 } | 488 } |
497 } | 489 } |
498 | 490 |
499 // ConfirmInfoBar, views::LinkController implementation: ----------------------- | 491 // ConfirmInfoBar, views::LinkController implementation: ----------------------- |
500 | 492 |
501 void ConfirmInfoBar::LinkActivated(views::Link* source, int event_flags) { | 493 void ConfirmInfoBar::LinkActivated(views::Link* source, int event_flags) { |
502 DCHECK(source == link_); | 494 DCHECK(source == link_); |
503 DCHECK(link_->IsVisible()); | 495 DCHECK(link_->IsVisible()); |
504 DCHECK(!link_->GetText().empty()); | 496 DCHECK(!link_->GetText().empty()); |
505 if (GetDelegate()->LinkClicked( | 497 if (delegate() && GetDelegate()->LinkClicked( |
506 event_utils::DispositionFromEventFlags(event_flags))) { | 498 event_utils::DispositionFromEventFlags(event_flags))) |
507 RemoveInfoBar(); | 499 RemoveInfoBar(); |
508 } | |
509 } | 500 } |
510 | 501 |
511 // ConfirmInfoBar, views::View overrides: -------------------------------------- | 502 // ConfirmInfoBar, views::View overrides: -------------------------------------- |
512 | 503 |
513 void ConfirmInfoBar::Layout() { | 504 void ConfirmInfoBar::Layout() { |
514 // First layout right aligned items (from right to left) in order to determine | 505 // First layout right aligned items (from right to left) in order to determine |
515 // the space avalable, then layout the left aligned items. | 506 // the space avalable, then layout the left aligned items. |
516 | 507 |
517 // Layout the close button. | 508 // Layout the close button. |
518 InfoBar::Layout(); | 509 InfoBar::Layout(); |
519 | 510 |
520 // Layout the cancel and OK buttons. | 511 // Layout the cancel and OK buttons. |
521 int available_width = AlertInfoBar::GetAvailableWidth(); | 512 int available_width = AlertInfoBar::GetAvailableWidth(); |
522 int ok_button_width = 0; | 513 int ok_button_width = 0; |
523 int cancel_button_width = 0; | 514 int cancel_button_width = 0; |
524 gfx::Size ok_ps = ok_button_->GetPreferredSize(); | 515 gfx::Size ok_ps = ok_button_->GetPreferredSize(); |
525 gfx::Size cancel_ps = cancel_button_->GetPreferredSize(); | 516 gfx::Size cancel_ps = cancel_button_->GetPreferredSize(); |
526 | 517 |
527 if (GetDelegate()->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK) { | 518 // Cache the button set so that once the delegate goes away we can still |
| 519 // Layout() (e.g. in the case of AnimateClose()). |
| 520 if (delegate()) |
| 521 cached_buttons_ = GetDelegate()->GetButtons(); |
| 522 if (cached_buttons_ & ConfirmInfoBarDelegate::BUTTON_OK) |
528 ok_button_width = ok_ps.width(); | 523 ok_button_width = ok_ps.width(); |
529 } else { | 524 else |
530 ok_button_->SetVisible(false); | 525 ok_button_->SetVisible(false); |
531 } | 526 if (cached_buttons_ & ConfirmInfoBarDelegate::BUTTON_CANCEL) |
532 if (GetDelegate()->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL) { | |
533 cancel_button_width = cancel_ps.width(); | 527 cancel_button_width = cancel_ps.width(); |
534 } else { | 528 else |
535 cancel_button_->SetVisible(false); | 529 cancel_button_->SetVisible(false); |
536 } | |
537 | 530 |
538 cancel_button_->SetBounds(available_width - cancel_button_width, | 531 cancel_button_->SetBounds(available_width - cancel_button_width, |
539 OffsetY(this, cancel_ps), cancel_ps.width(), | 532 OffsetY(this, cancel_ps), cancel_ps.width(), |
540 cancel_ps.height()); | 533 cancel_ps.height()); |
541 int spacing = cancel_button_width > 0 ? kButtonButtonSpacing : 0; | 534 int spacing = cancel_button_width > 0 ? kButtonButtonSpacing : 0; |
542 ok_button_->SetBounds(cancel_button_->x() - spacing - ok_button_width, | 535 ok_button_->SetBounds(cancel_button_->x() - spacing - ok_button_width, |
543 OffsetY(this, ok_ps), ok_ps.width(), ok_ps.height()); | 536 OffsetY(this, ok_ps), ok_ps.width(), ok_ps.height()); |
544 | 537 |
545 // Layout the icon and label. | 538 // Layout the icon and label. |
546 AlertInfoBar::Layout(); | 539 AlertInfoBar::Layout(); |
(...skipping 11 matching lines...) Expand all Loading... |
558 views::View* child) { | 551 views::View* child) { |
559 if (is_add && child == this && !initialized_) { | 552 if (is_add && child == this && !initialized_) { |
560 Init(); | 553 Init(); |
561 initialized_ = true; | 554 initialized_ = true; |
562 } | 555 } |
563 InfoBar::ViewHierarchyChanged(is_add, parent, child); | 556 InfoBar::ViewHierarchyChanged(is_add, parent, child); |
564 } | 557 } |
565 | 558 |
566 // ConfirmInfoBar, views::ButtonListener implementation: --------------- | 559 // ConfirmInfoBar, views::ButtonListener implementation: --------------- |
567 | 560 |
568 void ConfirmInfoBar::ButtonPressed( | 561 void ConfirmInfoBar::ButtonPressed(views::Button* sender, |
569 views::Button* sender, const views::Event& event) { | 562 const views::Event& event) { |
570 InfoBar::ButtonPressed(sender, event); | 563 InfoBar::ButtonPressed(sender, event); |
| 564 if (!GetDelegate()) |
| 565 return; |
571 if (sender == ok_button_) { | 566 if (sender == ok_button_) { |
572 if (GetDelegate()->Accept()) | 567 if (GetDelegate()->Accept()) |
573 RemoveInfoBar(); | 568 RemoveInfoBar(); |
574 } else if (sender == cancel_button_) { | 569 } else if (sender == cancel_button_) { |
575 if (GetDelegate()->Cancel()) | 570 if (GetDelegate()->Cancel()) |
576 RemoveInfoBar(); | 571 RemoveInfoBar(); |
577 } | 572 } |
578 } | 573 } |
579 | 574 |
580 // ConfirmInfoBar, InfoBar overrides: ------------------------------------------ | 575 // ConfirmInfoBar, InfoBar overrides: ------------------------------------------ |
(...skipping 24 matching lines...) Expand all Loading... |
605 | 600 |
606 InfoBar* LinkInfoBarDelegate::CreateInfoBar() { | 601 InfoBar* LinkInfoBarDelegate::CreateInfoBar() { |
607 return new LinkInfoBar(this); | 602 return new LinkInfoBar(this); |
608 } | 603 } |
609 | 604 |
610 // ConfirmInfoBarDelegate, InfoBarDelegate overrides: -------------------------- | 605 // ConfirmInfoBarDelegate, InfoBarDelegate overrides: -------------------------- |
611 | 606 |
612 InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() { | 607 InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() { |
613 return new ConfirmInfoBar(this); | 608 return new ConfirmInfoBar(this); |
614 } | 609 } |
OLD | NEW |