diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-24 20:38:03 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-24 20:38:03 +0000 |
commit | c3af31375c09cb9bf570efaafbdcabd0bdb1a24d (patch) | |
tree | ce0b6ddfdf6f32fd2eb33ec1cbd16859be22063d /chrome/browser/views/infobars | |
parent | 1051ccbdf5ebcaaa967db454393b85ed84fd36fb (diff) | |
download | chromium_src-c3af31375c09cb9bf570efaafbdcabd0bdb1a24d.zip chromium_src-c3af31375c09cb9bf570efaafbdcabd0bdb1a24d.tar.gz chromium_src-c3af31375c09cb9bf570efaafbdcabd0bdb1a24d.tar.bz2 |
Re-land r5882 with a crash fix.
http://codereview.chromium.org/11559
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5929 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views/infobars')
-rw-r--r-- | chrome/browser/views/infobars/infobar_container.cc | 4 | ||||
-rw-r--r-- | chrome/browser/views/infobars/infobars.cc | 37 | ||||
-rw-r--r-- | chrome/browser/views/infobars/infobars.h | 10 |
3 files changed, 42 insertions, 9 deletions
diff --git a/chrome/browser/views/infobars/infobar_container.cc b/chrome/browser/views/infobars/infobar_container.cc index 2fe7a35..bb48b12 100644 --- a/chrome/browser/views/infobars/infobar_container.cc +++ b/chrome/browser/views/infobars/infobar_container.cc @@ -103,7 +103,7 @@ void InfoBarContainer::UpdateInfoBars() { // Clear out all the old child views. RemoveAllChildViews(true); - for (size_t i = 0; i < tab_contents_->infobar_delegate_count(); ++i) { + for (int i = 0; i < tab_contents_->infobar_delegate_count(); ++i) { InfoBarDelegate* delegate = tab_contents_->GetInfoBarDelegateAt(i); InfoBar* infobar = delegate->CreateInfoBar(); infobar->set_container(this); @@ -120,7 +120,7 @@ void InfoBarContainer::AddInfoBar(InfoBarDelegate* delegate) { } void InfoBarContainer::RemoveInfoBar(InfoBarDelegate* delegate) { - size_t index = 0; + int index = 0; for (; index < tab_contents_->infobar_delegate_count(); ++index) { if (tab_contents_->GetInfoBarDelegateAt(index) == delegate) break; diff --git a/chrome/browser/views/infobars/infobars.cc b/chrome/browser/views/infobars/infobars.cc index 5733d33..c9b6f2e 100644 --- a/chrome/browser/views/infobars/infobars.cc +++ b/chrome/browser/views/infobars/infobars.cc @@ -11,8 +11,10 @@ #include "chrome/common/slide_animation.h" #include "chrome/views/background.h" #include "chrome/views/button.h" +#include "chrome/views/external_focus_tracker.h" #include "chrome/views/image_view.h" #include "chrome/views/label.h" +#include "chrome/views/widget.h" #include "generated_resources.h" @@ -102,6 +104,8 @@ void InfoBar::AnimateClose() { void InfoBar::Close() { GetParent()->RemoveChildView(this); + if (focus_tracker_.get()) + focus_tracker_->FocusLastFocusedExternalView(); if (delegate()) delegate()->InfoBarClosed(); delete this; @@ -122,6 +126,25 @@ void InfoBar::Layout() { } +void InfoBar::ViewHierarchyChanged(bool is_add, views::View* parent, + views::View* child) { + if (child == this) { + views::Widget* widget = GetWidget(); + if (is_add && widget) { + // When we're added to a view hierarchy within a widget, we create an + // external focus tracker to track what was focused in case we obtain + // focus so that we can restore focus when we're removed. + focus_tracker_.reset( + new views::ExternalFocusTracker(this, + views::FocusManager::GetFocusManager(widget->GetHWND()))); + } else if (focus_tracker_.get()) { + // When we're removed from a view hierarchy, our focus manager is no + // longer valid. + focus_tracker_->SetFocusManager(NULL); + } + } +} + // InfoBar, protected: --------------------------------------------------------- int InfoBar::GetAvailableWidth() const { @@ -199,6 +222,12 @@ ConfirmInfoBar::ConfirmInfoBar(ConfirmInfoBarDelegate* delegate) cancel_button_(NULL), initialized_(false), AlertInfoBar(delegate) { + ok_button_ = new views::NativeButton( + delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK)); + ok_button_->SetListener(this); + cancel_button_ = new views::NativeButton( + delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL)); + cancel_button_->SetListener(this); } ConfirmInfoBar::~ConfirmInfoBar() { @@ -232,6 +261,7 @@ void ConfirmInfoBar::Layout() { void ConfirmInfoBar::ViewHierarchyChanged(bool is_add, views::View* parent, views::View* child) { + InfoBar::ViewHierarchyChanged(is_add, parent, child); if (is_add && child == this && !initialized_) { Init(); initialized_ = true; @@ -267,14 +297,7 @@ ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() { } void ConfirmInfoBar::Init() { - ok_button_ = new views::NativeButton( - GetDelegate()->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK)); - ok_button_->SetListener(this); AddChildView(ok_button_); - - cancel_button_ = new views::NativeButton( - GetDelegate()->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL)); - cancel_button_->SetListener(this); AddChildView(cancel_button_); } diff --git a/chrome/browser/views/infobars/infobars.h b/chrome/browser/views/infobars/infobars.h index 1e02f96..7b94735 100644 --- a/chrome/browser/views/infobars/infobars.h +++ b/chrome/browser/views/infobars/infobars.h @@ -13,6 +13,7 @@ class InfoBarContainer; class SlideAnimation; namespace views { class Button; +class ExternalFocusTracker; class ImageView; class Label; } @@ -52,6 +53,11 @@ class InfoBar : public views::View, virtual void Layout(); protected: + // Overridden from views::View: + virtual void ViewHierarchyChanged(bool is_add, + views::View* parent, + views::View* child); + // Returns the available width of the View for use by child view layout, // excluding the close button. virtual int GetAvailableWidth() const; @@ -76,6 +82,10 @@ class InfoBar : public views::View, // The animation that runs when the InfoBar is opened or closed. scoped_ptr<SlideAnimation> animation_; + // Tracks and stores the last focused view which is not the InfoBar or any of + // its children. Used to restore focus once the InfoBar is closed. + scoped_ptr<views::ExternalFocusTracker> focus_tracker_; + DISALLOW_COPY_AND_ASSIGN(InfoBar); }; |