diff options
Diffstat (limited to 'chrome/browser/ui/views/infobars/infobar_view.cc')
-rw-r--r-- | chrome/browser/ui/views/infobars/infobar_view.cc | 254 |
1 files changed, 106 insertions, 148 deletions
diff --git a/chrome/browser/ui/views/infobars/infobar_view.cc b/chrome/browser/ui/views/infobars/infobar_view.cc index 5e90a16..5871c96 100644 --- a/chrome/browser/ui/views/infobars/infobar_view.cc +++ b/chrome/browser/ui/views/infobars/infobar_view.cc @@ -27,7 +27,7 @@ #endif // static -const double InfoBarView::kDefaultTargetHeight = 36.0; +const int InfoBarView::kDefaultTargetHeight = 36; const int InfoBarView::kHorizontalPadding = 6; const int InfoBarView::kIconLabelSpacing = 6; const int InfoBarView::kButtonButtonSpacing = 10; @@ -35,8 +35,6 @@ const int InfoBarView::kEndOfLabelSpacing = 16; const int InfoBarView::kCloseButtonSpacing = 12; const int InfoBarView::kButtonInLabelSpacing = 5; -// InfoBarView, public: ------------------------------------------------------- - InfoBarView::InfoBarView(InfoBarDelegate* delegate) : InfoBar(delegate), delegate_(delegate), @@ -44,24 +42,14 @@ InfoBarView::InfoBarView(InfoBarDelegate* delegate) close_button_(new views::ImageButton(this))), ALLOW_THIS_IN_INITIALIZER_LIST(delete_factory_(this)), target_height_(kDefaultTargetHeight) { - // We delete ourselves when we're removed from the view hierarchy. + // InfoBar deletes itself at the appropriate time. set_parent_owned(false); - set_background(new InfoBarBackground(delegate->GetInfoBarType())); - - switch (delegate->GetInfoBarType()) { - case InfoBarDelegate::WARNING_TYPE: - SetAccessibleName( - l10n_util::GetStringUTF16(IDS_ACCNAME_INFOBAR_WARNING)); - break; - case InfoBarDelegate::PAGE_ACTION_TYPE: - SetAccessibleName( - l10n_util::GetStringUTF16(IDS_ACCNAME_INFOBAR_PAGE_ACTION)); - break; - default: - NOTREACHED(); - break; - } + InfoBarDelegate::Type infobar_type = delegate->GetInfoBarType(); + set_background(new InfoBarBackground(infobar_type)); + SetAccessibleName(l10n_util::GetStringUTF16( + (infobar_type == InfoBarDelegate::WARNING_TYPE) ? + IDS_ACCNAME_INFOBAR_WARNING : IDS_ACCNAME_INFOBAR_PAGE_ACTION)); ResourceBundle& rb = ResourceBundle::GetSharedInstance(); close_button_->SetImage(views::CustomButton::BS_NORMAL, @@ -72,13 +60,48 @@ InfoBarView::InfoBarView(InfoBarDelegate* delegate) rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); close_button_->SetAccessibleName( l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE)); + close_button_->SetFocusable(true); AddChildView(close_button_); animation_.reset(new ui::SlideAnimation(this)); animation_->SetTweenType(ui::Tween::LINEAR); } -InfoBarView::~InfoBarView() { +void InfoBarView::AnimateOpen() { + animation_->Show(); +} + +void InfoBarView::Open() { + // Set the animation value to 1.0 so that GetPreferredSize() returns the right + // size. + animation_->Reset(1.0); + if (container_) + container_->InfoBarAnimated(false); +} + +void InfoBarView::AnimateClose() { + bool restore_focus = true; +#if defined(OS_WIN) + // Do not restore focus (and active state with it) on Windows if some other + // top-level window became active. + if (GetWidget() && + !ui::DoesWindowBelongToActiveWindow(GetWidget()->GetNativeView())) { + restore_focus = false; + } +#endif // defined(OS_WIN) + DestroyFocusTracker(restore_focus); + animation_->Hide(); +} + +void InfoBarView::Close() { + GetParent()->RemoveChildView(this); + // Note that we only tell the delegate we're closed here, and not when we're + // simply destroyed (by virtue of a tab switch or being moved from window to + // window), since this action can cause the delegate to destroy itself. + if (delegate_) { + delegate_->InfoBarClosed(); + delegate_ = NULL; + } } void InfoBarView::PaintArrow(gfx::Canvas* canvas, @@ -133,22 +156,14 @@ void InfoBarView::PaintArrow(gfx::Canvas* canvas, canvas_skia->drawPath(border_path, paint); } -// InfoBarView, views::View overrides: ---------------------------------------- - -AccessibilityTypes::Role InfoBarView::GetAccessibleRole() { - return AccessibilityTypes::ROLE_ALERT; -} - -gfx::Size InfoBarView::GetPreferredSize() { - int height = static_cast<int>(target_height_ * animation_->GetCurrentValue()); - return gfx::Size(0, height); +InfoBarView::~InfoBarView() { } void InfoBarView::Layout() { - gfx::Size button_ps = close_button_->GetPreferredSize(); - close_button_->SetBounds(width() - kHorizontalPadding - button_ps.width(), - OffsetY(this, button_ps), button_ps.width(), - button_ps.height()); + gfx::Size button_size = close_button_->GetPreferredSize(); + close_button_->SetBounds(width() - kHorizontalPadding - button_size.width(), + OffsetY(this, button_size), button_size.width(), + button_size.height()); } void InfoBarView::ViewHierarchyChanged(bool is_add, @@ -156,27 +171,58 @@ void InfoBarView::ViewHierarchyChanged(bool is_add, views::View* child) { if (child == this) { if (is_add) { - InfoBarAdded(); + // The container_ pointer must be set before adding to the view hierarchy. + DCHECK(container_); +#if defined(OS_WIN) + // 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. + views::Widget* widget = GetWidget(); + if (widget) { + focus_tracker_.reset( + new views::ExternalFocusTracker(this, GetFocusManager())); + } +#endif + if (GetFocusManager()) + GetFocusManager()->AddFocusChangeListener(this); + NotifyAccessibilityEvent(AccessibilityTypes::EVENT_ALERT); } else { - InfoBarRemoved(); + DestroyFocusTracker(false); + // NULL our container_ pointer so that if Animation::Stop results in + // AnimationEnded being called, we do not try and delete ourselves twice. + container_ = NULL; + animation_->Stop(); + // Finally, clean ourselves up when we're removed from the view hierarchy + // since no-one refers to us now. + MessageLoop::current()->PostTask(FROM_HERE, + delete_factory_.NewRunnableMethod(&InfoBarView::DeleteSelf)); + if (GetFocusManager()) + GetFocusManager()->RemoveFocusChangeListener(this); } } - if (GetWidget() && GetWidget()->IsAccessibleWidget()) { - // For accessibility, make the close button the last child view. - if (parent == this && child != close_button_ && - HasChildView(close_button_) && - GetChildViewAt(GetChildViewCount() - 1) != close_button_) { - RemoveChildView(close_button_); - AddChildView(close_button_); - } + // For accessibility, ensure the close button is the last child view. + if ((parent == this) && (child != close_button_) && + HasChildView(close_button_) && + (GetChildViewAt(GetChildViewCount() - 1) != close_button_)) { + RemoveChildView(close_button_); + AddChildView(close_button_); + } +} - // Allow screen reader users to focus the close button. - close_button_->SetFocusable(true); +void InfoBarView::ButtonPressed(views::Button* sender, + const views::Event& event) { + if (sender == close_button_) { + if (delegate_) + delegate_->InfoBarDismissed(); + RemoveInfoBar(); } } -// InfoBarView, protected: ---------------------------------------------------- +void InfoBarView::AnimationProgressed(const ui::Animation* animation) { + if (container_) + container_->InfoBarAnimated(true); +} int InfoBarView::GetAvailableWidth() const { return close_button_->x() - kCloseButtonSpacing; @@ -187,43 +233,29 @@ void InfoBarView::RemoveInfoBar() const { container_->RemoveDelegate(delegate()); } -int InfoBarView::CenterY(const gfx::Size prefsize) { - return std::max((static_cast<int>(target_height_) - - prefsize.height()) / 2, 0); +int InfoBarView::CenterY(const gfx::Size prefsize) const { + return std::max((target_height_ - prefsize.height()) / 2, 0); } -int InfoBarView::OffsetY(views::View* parent, const gfx::Size prefsize) { - return CenterY(prefsize) - - (static_cast<int>(target_height_) - parent->height()); +int InfoBarView::OffsetY(views::View* parent, const gfx::Size prefsize) const { + return CenterY(prefsize) - (target_height_ - parent->height()); } -// InfoBarView, views::ButtonListener implementation: ------------------------- - -void InfoBarView::ButtonPressed(views::Button* sender, - const views::Event& event) { - if (sender == close_button_) { - if (delegate_) - delegate_->InfoBarDismissed(); - RemoveInfoBar(); - } +AccessibilityTypes::Role InfoBarView::GetAccessibleRole() { + return AccessibilityTypes::ROLE_ALERT; } -// InfoBarView, views::FocusChangeListener implementation: -------------------- +gfx::Size InfoBarView::GetPreferredSize() { + int height = static_cast<int>(target_height_ * animation_->GetCurrentValue()); + return gfx::Size(0, height); +} void InfoBarView::FocusWillChange(View* focused_before, View* focused_now) { // This will trigger some screen readers to read the entire contents of this // infobar. - if (focused_before && focused_now && - !this->IsParentOf(focused_before) && this->IsParentOf(focused_now)) { + if (focused_before && focused_now && !this->IsParentOf(focused_before) && + this->IsParentOf(focused_now)) NotifyAccessibilityEvent(AccessibilityTypes::EVENT_ALERT); - } -} - -// InfoBarView, ui::AnimationDelegate implementation: ------------------------- - -void InfoBarView::AnimationProgressed(const ui::Animation* animation) { - if (container_) - container_->InfoBarAnimated(true); } void InfoBarView::AnimationEnded(const ui::Animation* animation) { @@ -235,86 +267,12 @@ void InfoBarView::AnimationEnded(const ui::Animation* animation) { } } -// InfoBarView, private: ------------------------------------------------------ - -void InfoBarView::AnimateOpen() { - animation_->Show(); -} - -void InfoBarView::Open() { - // Set the animation value to 1.0 so that GetPreferredSize() returns the right - // size. - animation_->Reset(1.0); - if (container_) - container_->InfoBarAnimated(false); -} - -void InfoBarView::AnimateClose() { - bool restore_focus = true; -#if defined(OS_WIN) - // Do not restore focus (and active state with it) on Windows if some other - // top-level window became active. - if (GetWidget() && - !ui::DoesWindowBelongToActiveWindow(GetWidget()->GetNativeView())) { - restore_focus = false; - } -#endif // defined(OS_WIN) - DestroyFocusTracker(restore_focus); - animation_->Hide(); -} - -void InfoBarView::Close() { - GetParent()->RemoveChildView(this); - // Note that we only tell the delegate we're closed here, and not when we're - // simply destroyed (by virtue of a tab switch or being moved from window to - // window), since this action can cause the delegate to destroy itself. - if (delegate_) { - delegate_->InfoBarClosed(); - delegate_ = NULL; - } -} - -void InfoBarView::InfoBarAdded() { - // The container_ pointer must be set before adding to the view hierarchy. - DCHECK(container_); -#if defined(OS_WIN) - // 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. - views::Widget* widget = GetWidget(); - if (widget) { - focus_tracker_.reset(new views::ExternalFocusTracker(this, - GetFocusManager())); - } -#endif - - if (GetFocusManager()) - GetFocusManager()->AddFocusChangeListener(this); - - NotifyAccessibilityEvent(AccessibilityTypes::EVENT_ALERT); -} - -void InfoBarView::InfoBarRemoved() { - DestroyFocusTracker(false); - // NULL our container_ pointer so that if Animation::Stop results in - // AnimationEnded being called, we do not try and delete ourselves twice. - container_ = NULL; - animation_->Stop(); - // Finally, clean ourselves up when we're removed from the view hierarchy - // since no-one refers to us now. - MessageLoop::current()->PostTask(FROM_HERE, - delete_factory_.NewRunnableMethod(&InfoBarView::DeleteSelf)); - - if (GetFocusManager()) - GetFocusManager()->RemoveFocusChangeListener(this); -} - void InfoBarView::DestroyFocusTracker(bool restore_focus) { - if (focus_tracker_.get()) { + if (focus_tracker_ != NULL) { if (restore_focus) focus_tracker_->FocusLastFocusedExternalView(); focus_tracker_->SetFocusManager(NULL); - focus_tracker_.reset(NULL); + focus_tracker_.reset(); } } |