diff options
-rw-r--r-- | chrome/browser/extensions/extension_install_ui.cc | 16 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.cc | 22 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.h | 4 | ||||
-rw-r--r-- | chrome/browser/views/infobars/infobar_container.cc | 37 | ||||
-rw-r--r-- | chrome/browser/views/infobars/infobar_container.h | 14 | ||||
-rw-r--r-- | chrome/common/notification_type.h | 7 |
6 files changed, 84 insertions, 16 deletions
diff --git a/chrome/browser/extensions/extension_install_ui.cc b/chrome/browser/extensions/extension_install_ui.cc index 7d879c5..cfc5e54 100644 --- a/chrome/browser/extensions/extension_install_ui.cc +++ b/chrome/browser/extensions/extension_install_ui.cc @@ -112,16 +112,22 @@ void ExtensionInstallUI::ShowThemeInfoBar(Extension* extension) { if (!tab_contents) return; - // First remove any previous theme preview infobar. + // First find any previous theme preview infobars. + InfoBarDelegate* old_delegate = NULL; for (int i = 0; i < tab_contents->infobar_delegate_count(); ++i) { InfoBarDelegate* delegate = tab_contents->GetInfoBarDelegateAt(i); if (delegate->AsThemePreviewInfobarDelegate()) { - tab_contents->RemoveInfoBar(delegate); + old_delegate = delegate; break; } } - // Now add the new one. - tab_contents->AddInfoBar(new ThemePreviewInfobarDelegate( - tab_contents, extension->name())); + // Then either replace that old one or add a new one. + InfoBarDelegate* new_delegate = new ThemePreviewInfobarDelegate(tab_contents, + extension->name()); + + if (old_delegate) + tab_contents->ReplaceInfoBar(old_delegate, new_delegate); + else + tab_contents->AddInfoBar(new_delegate); } diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 5b816f19..5f6de7c 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -890,6 +890,28 @@ void TabContents::RemoveInfoBar(InfoBarDelegate* delegate) { } } +void TabContents::ReplaceInfoBar(InfoBarDelegate* old_delegate, + InfoBarDelegate* new_delegate) { + std::vector<InfoBarDelegate*>::iterator it = + find(infobar_delegates_.begin(), infobar_delegates_.end(), old_delegate); + DCHECK(it != infobar_delegates_.end()); + + // Notify the container about the change of plans. + scoped_ptr<std::pair<InfoBarDelegate*, InfoBarDelegate*> > details( + new std::pair<InfoBarDelegate*, InfoBarDelegate*>( + old_delegate, new_delegate)); + NotificationService::current()->Notify( + NotificationType::TAB_CONTENTS_INFOBAR_REPLACED, + Source<TabContents>(this), + Details<std::pair<InfoBarDelegate*, InfoBarDelegate*> >(details.get())); + + // Remove the old one. + infobar_delegates_.erase(it); + + // Add the new one. + infobar_delegates_.push_back(new_delegate); +} + bool TabContents::IsBookmarkBarAlwaysVisible() { // See GetDOMUIForCurrentState() comment for more info. This case is very // similar, but for non-first loads, we want to use the committed entry. This diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index 0536436..e8f7d14 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -401,6 +401,10 @@ class TabContents : public PageNavigator, // Removes the InfoBar for the specified |delegate|. void RemoveInfoBar(InfoBarDelegate* delegate); + // Replaces one infobar with another, without any animation in between. + void ReplaceInfoBar(InfoBarDelegate* old_delegate, + InfoBarDelegate* new_delegate); + // Enumeration and access functions. int infobar_delegate_count() const { return infobar_delegates_.size(); } InfoBarDelegate* GetInfoBarDelegateAt(int index) { diff --git a/chrome/browser/views/infobars/infobar_container.cc b/chrome/browser/views/infobars/infobar_container.cc index 530236c..792729b 100644 --- a/chrome/browser/views/infobars/infobar_container.cc +++ b/chrome/browser/views/infobars/infobar_container.cc @@ -38,6 +38,8 @@ void InfoBarContainer::ChangeTabContents(TabContents* contents) { tc_source); registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, tc_source); + registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_REPLACED, + tc_source); } } @@ -109,9 +111,13 @@ void InfoBarContainer::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { if (type == NotificationType::TAB_CONTENTS_INFOBAR_ADDED) { - AddInfoBar(Details<InfoBarDelegate>(details).ptr()); + AddInfoBar(Details<InfoBarDelegate>(details).ptr(), true); // animated } else if (type == NotificationType::TAB_CONTENTS_INFOBAR_REMOVED) { - RemoveInfoBar(Details<InfoBarDelegate>(details).ptr()); + RemoveInfoBar(Details<InfoBarDelegate>(details).ptr(), true); // animated + } else if (type == NotificationType::TAB_CONTENTS_INFOBAR_REPLACED) { + std::pair<InfoBarDelegate*, InfoBarDelegate*>* delegates = + Details<std::pair<InfoBarDelegate*, InfoBarDelegate*> >(details).ptr(); + ReplaceInfoBar(delegates->first, delegates->second); } else { NOTREACHED(); } @@ -129,20 +135,37 @@ void InfoBarContainer::UpdateInfoBars() { } } -void InfoBarContainer::AddInfoBar(InfoBarDelegate* delegate) { +void InfoBarContainer::AddInfoBar(InfoBarDelegate* delegate, + bool use_animation) { InfoBar* infobar = delegate->CreateInfoBar(); infobar->set_container(this); - infobar->AnimateOpen(); AddChildView(infobar); + + if (use_animation) + infobar->AnimateOpen(); + else + infobar->Open(); } -void InfoBarContainer::RemoveInfoBar(InfoBarDelegate* delegate) { +void InfoBarContainer::RemoveInfoBar(InfoBarDelegate* delegate, + bool use_animation) { int index = 0; for (; index < tab_contents_->infobar_delegate_count(); ++index) { if (tab_contents_->GetInfoBarDelegateAt(index) == delegate) break; } - // The View will be removed once the Close animation completes. - static_cast<InfoBar*>(GetChildViewAt(index))->AnimateClose(); + InfoBar* infobar = static_cast<InfoBar*>(GetChildViewAt(index)); + if (use_animation) { + // The View will be removed once the Close animation completes. + infobar->AnimateClose(); + } else { + infobar->Close(); + } +} + +void InfoBarContainer::ReplaceInfoBar(InfoBarDelegate* old_delegate, + InfoBarDelegate* new_delegate) { + RemoveInfoBar(old_delegate, false); // no animation + AddInfoBar(new_delegate, false); // no animation } diff --git a/chrome/browser/views/infobars/infobar_container.h b/chrome/browser/views/infobars/infobar_container.h index 063ba26..b5ea0f0 100644 --- a/chrome/browser/views/infobars/infobar_container.h +++ b/chrome/browser/views/infobars/infobar_container.h @@ -57,13 +57,19 @@ class InfoBarContainer : public views::View, void UpdateInfoBars(); // Adds an InfoBar for the specified delegate, in response to a notification - // from the selected TabContents. The InfoBar's appearance will be animated. - void AddInfoBar(InfoBarDelegate* delegate); + // from the selected TabContents. The InfoBar's appearance will be animated + // if |use_animation| is true. + void AddInfoBar(InfoBarDelegate* delegate, bool use_animation); // Removes an InfoBar for the specified delegate, in response to a // notification from the selected TabContents. The InfoBar's disappearance - // will be animated. - void RemoveInfoBar(InfoBarDelegate* delegate); + // will be animated if |use_animation| is true. + void RemoveInfoBar(InfoBarDelegate* delegate, bool use_animation); + + // Replaces an InfoBar for the specified delegate with a new one. There is no + // animation. + void ReplaceInfoBar(InfoBarDelegate* old_delegate, + InfoBarDelegate* new_delegate); NotificationRegistrar registrar_; diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h index 7a95f9a..2a04ffe 100644 --- a/chrome/common/notification_type.h +++ b/chrome/common/notification_type.h @@ -280,6 +280,13 @@ class NotificationType { // InfoBarDelegate interface for the InfoBar that was removed. TAB_CONTENTS_INFOBAR_REMOVED, + // This message is sent when an InfoBar is replacing another infobar in a + // TabContents. The source is a Source<TabContents> with a pointer to the + // TabContents the InfoBar was removed from. The details is a + // Details<std::pair<InfoBarDelegate*, InfoBarDelegate*> > with a pointer + // to the old and new InfoBarDelegates, respectively. + TAB_CONTENTS_INFOBAR_REPLACED, + // This is sent when an externally hosted tab is created. The details // contain the ExternalTabContainer that contains the tab EXTERNAL_TAB_CREATED, |