diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-21 22:27:24 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-21 22:27:24 +0000 |
commit | 616ed5a653d4bc13b4633d7c7b85d2f0c73bfd72 (patch) | |
tree | 04b8cd92d18cd6e1ff54e46c6c32b0d70391a831 /chrome/browser/views | |
parent | c7eeed7fa25e06ec3d0367a74d2b43671958c5d3 (diff) | |
download | chromium_src-616ed5a653d4bc13b4633d7c7b85d2f0c73bfd72.zip chromium_src-616ed5a653d4bc13b4633d7c7b85d2f0c73bfd72.tar.gz chromium_src-616ed5a653d4bc13b4633d7c7b85d2f0c73bfd72.tar.bz2 |
Beginnings of a new InfoBar system.
This implements AlertInfoBar and InfoBarContainer. It also makes the crashed plugin/js oom infobars use this new system.
Design Doc: http://dev.chromium.org/developers/design-documents/info-barshttp://crbug.com/4620
Review URL: http://codereview.chromium.org/11318
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5856 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views')
-rw-r--r-- | chrome/browser/views/browser_views.vcproj | 16 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view.cc | 35 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view.h | 4 | ||||
-rw-r--r-- | chrome/browser/views/infobars/infobar_container.cc | 131 | ||||
-rw-r--r-- | chrome/browser/views/infobars/infobar_container.h | 73 | ||||
-rw-r--r-- | chrome/browser/views/infobars/infobars.cc | 291 | ||||
-rw-r--r-- | chrome/browser/views/infobars/infobars.h | 138 |
7 files changed, 679 insertions, 9 deletions
diff --git a/chrome/browser/views/browser_views.vcproj b/chrome/browser/views/browser_views.vcproj index 5a543cd..f7ca623 100644 --- a/chrome/browser/views/browser_views.vcproj +++ b/chrome/browser/views/browser_views.vcproj @@ -216,6 +216,22 @@ RelativePath=".\info_bar_view.h" > </File> + <File + RelativePath=".\infobars\infobar_container.cc" + > + </File> + <File + RelativePath=".\infobars\infobar_container.h" + > + </File> + <File + RelativePath=".\infobars\infobars.cc" + > + </File> + <File + RelativePath=".\infobars\infobars.h" + > + </File> </Filter> <Filter Name="Options" diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index 8dbeb98..c3b5d07 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -25,6 +25,7 @@ #include "chrome/browser/views/frame/browser_frame.h" #include "chrome/browser/views/html_dialog_view.h" #include "chrome/browser/views/importer_view.h" +#include "chrome/browser/views/infobars/infobar_container.h" #include "chrome/browser/views/keyword_editor_view.h" #include "chrome/browser/views/password_manager_view.h" #include "chrome/browser/views/status_bubble.h" @@ -338,6 +339,9 @@ void BrowserView::Init() { toolbar_->Init(browser_->profile()); toolbar_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TOOLBAR)); + infobar_container_ = new InfoBarContainer(this); + AddChildView(infobar_container_); + contents_container_ = new TabContentsContainerView; set_contents_view(contents_container_); AddChildView(contents_container_); @@ -645,7 +649,9 @@ void BrowserView::TabSelectedAt(TabContents* old_contents, if (old_contents) old_contents->StoreFocus(); - // Tell the frame what happened so that the TabContents gets resized, etc. + // Update various elements that are interested in knowing the current + // TabContents. + infobar_container_->ChangeTabContents(new_contents); contents_container_->SetTabContents(new_contents); // TODO(beng): This should be called automatically by SetTabContents, but I // am striving for parity now rather than cleanliness. This is @@ -1055,7 +1061,7 @@ int BrowserView::LayoutBookmarkAndInfoBars(int top) { // the Bookmark bar isn't visible on all tabs, then we need to show the // Info bar _above_ the Bookmark bar, since the Bookmark bar is styled to // look like it's part of the New Tab Page... - if (active_info_bar_ && active_bookmark_bar_ && + if (active_bookmark_bar_ && bookmark_bar_view_->IsNewTabPage() && !bookmark_bar_view_->IsAlwaysShown()) { top = LayoutInfoBar(top); @@ -1078,13 +1084,21 @@ int BrowserView::LayoutBookmarkBar(int top) { return top; } int BrowserView::LayoutInfoBar(int top) { - if (SupportsWindowFeature(FEATURE_INFOBAR) && active_info_bar_) { - gfx::Size ps = active_info_bar_->GetPreferredSize(); - active_info_bar_->SetBounds(0, top, width(), ps.height()); + if (SupportsWindowFeature(FEATURE_INFOBAR)) { + // Layout the new infobar. + gfx::Size ps = infobar_container_->GetPreferredSize(); + infobar_container_->SetBounds(0, top, width(), ps.height()); top += ps.height(); - if (SupportsWindowFeature(FEATURE_BOOKMARKBAR) && active_bookmark_bar_ && - !show_bookmark_bar_pref_.GetValue()) { - top -= kSeparationLineHeight; + + if (active_info_bar_) { + // Layout the old infobar. + ps = active_info_bar_->GetPreferredSize(); + active_info_bar_->SetBounds(0, top, width(), ps.height()); + top += ps.height(); + if (SupportsWindowFeature(FEATURE_BOOKMARKBAR) && active_bookmark_bar_ && + !show_bookmark_bar_pref_.GetValue()) { + top -= kSeparationLineHeight; + } } } return top; @@ -1131,7 +1145,10 @@ bool BrowserView::MaybeShowInfoBar(TabContents* contents) { if (contents && contents->AsWebContents() && contents->AsWebContents()->view()->IsInfoBarVisible()) new_info_bar = contents->AsWebContents()->view()->GetInfoBarView(); - return UpdateChildViewAndLayout(new_info_bar, &active_info_bar_); + UpdateChildViewAndLayout(new_info_bar, &active_info_bar_); + + // TODO(beng): remove this function once the InfoBar rejiggering is complete. + return true; } bool BrowserView::MaybeShowDownloadShelf(TabContents* contents) { diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h index d777f5a..172a1db 100644 --- a/chrome/browser/views/frame/browser_view.h +++ b/chrome/browser/views/frame/browser_view.h @@ -22,6 +22,7 @@ class BookmarkBarView; class Browser; class BrowserToolbarView; class EncodingMenuControllerDelegate; +class InfoBarContainer; class Menu; class StatusBubble; class TabContentsContainerView; @@ -343,6 +344,9 @@ class BrowserView : public BrowserWindow, // The Bookmark Bar View for this window. Lazily created. scoped_ptr<BookmarkBarView> bookmark_bar_view_; + // The InfoBarContainer that contains InfoBars for the current tab. + InfoBarContainer* infobar_container_; + // The view that contains the selected TabContents. TabContentsContainerView* contents_container_; diff --git a/chrome/browser/views/infobars/infobar_container.cc b/chrome/browser/views/infobars/infobar_container.cc new file mode 100644 index 0000000..2fe7a35 --- /dev/null +++ b/chrome/browser/views/infobars/infobar_container.cc @@ -0,0 +1,131 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/views/infobars/infobar_container.h" + +#include "chrome/browser/infobar_delegate.h" +#include "chrome/browser/tab_contents.h" +#include "chrome/browser/views/frame/browser_view.h" +#include "chrome/browser/views/infobars/infobars.h" +#include "chrome/common/notification_types.h" + +// InfoBarContainer, public: --------------------------------------------------- + +InfoBarContainer::InfoBarContainer(BrowserView* browser_view) + : browser_view_(browser_view), + tab_contents_(NULL) { + +} + +InfoBarContainer::~InfoBarContainer() { + ChangeTabContents(NULL); +} + +void InfoBarContainer::ChangeTabContents(TabContents* contents) { + if (tab_contents_) { + NotificationService::current()->RemoveObserver( + this, NOTIFY_TAB_CONTENTS_INFOBAR_ADDED, + Source<TabContents>(tab_contents_)); + NotificationService::current()->RemoveObserver( + this, NOTIFY_TAB_CONTENTS_INFOBAR_REMOVED, + Source<TabContents>(tab_contents_)); + } + tab_contents_ = contents; + if (tab_contents_) { + UpdateInfoBars(); + NotificationService::current()->AddObserver( + this, NOTIFY_TAB_CONTENTS_INFOBAR_ADDED, + Source<TabContents>(tab_contents_)); + NotificationService::current()->AddObserver( + this, NOTIFY_TAB_CONTENTS_INFOBAR_REMOVED, + Source<TabContents>(tab_contents_)); + } +} + +void InfoBarContainer::InfoBarAnimated(bool completed) { + browser_view_->SelectedTabToolbarSizeChanged(!completed); +} + +void InfoBarContainer::RemoveDelegate(InfoBarDelegate* delegate) { + tab_contents_->RemoveInfoBar(delegate); +} + +// InfoBarContainer, views::View overrides: ------------------------------------ + +gfx::Size InfoBarContainer::GetPreferredSize() { + // We do not have a preferred width (we will expand to fit the available width + // of the BrowserView). Our preferred height is the sum of the preferred + // heights of the InfoBars contained within us. + int height = 0; + for (int i = 0; i < GetChildViewCount(); ++i) + height += GetChildViewAt(i)->GetPreferredSize().height(); + return gfx::Size(0, height); +} + +void InfoBarContainer::Layout() { + int top = 0; + for (int i = 0; i < GetChildViewCount(); ++i) { + views::View* child = GetChildViewAt(i); + gfx::Size ps = child->GetPreferredSize(); + child->SetBounds(0, top, width(), ps.height()); + top += ps.height(); + } +} + +void InfoBarContainer::ViewHierarchyChanged(bool is_add, + views::View* parent, + views::View* child) { + if (parent == this && child->GetParent() == this) { + // An InfoBar child was added or removed. Tell the BrowserView it needs to + // re-layout since our preferred size will have changed. + browser_view_->SelectedTabToolbarSizeChanged(false); + } +} + +// InfoBarContainer, NotificationObserver implementation: ---------------------- + +void InfoBarContainer::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type == NOTIFY_TAB_CONTENTS_INFOBAR_ADDED) { + AddInfoBar(Details<InfoBarDelegate>(details).ptr()); + } else if (type == NOTIFY_TAB_CONTENTS_INFOBAR_REMOVED) { + RemoveInfoBar(Details<InfoBarDelegate>(details).ptr()); + } else { + NOTREACHED(); + } +} + +// InfoBarContainer, private: -------------------------------------------------- + +void InfoBarContainer::UpdateInfoBars() { + // Clear out all the old child views. + RemoveAllChildViews(true); + + for (size_t i = 0; i < tab_contents_->infobar_delegate_count(); ++i) { + InfoBarDelegate* delegate = tab_contents_->GetInfoBarDelegateAt(i); + InfoBar* infobar = delegate->CreateInfoBar(); + infobar->set_container(this); + AddChildView(infobar); + infobar->Open(); + } +} + +void InfoBarContainer::AddInfoBar(InfoBarDelegate* delegate) { + InfoBar* infobar = delegate->CreateInfoBar(); + infobar->set_container(this); + infobar->AnimateOpen(); + AddChildView(infobar); +} + +void InfoBarContainer::RemoveInfoBar(InfoBarDelegate* delegate) { + size_t 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(); +} diff --git a/chrome/browser/views/infobars/infobar_container.h b/chrome/browser/views/infobars/infobar_container.h new file mode 100644 index 0000000..43c5280 --- /dev/null +++ b/chrome/browser/views/infobars/infobar_container.h @@ -0,0 +1,73 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_VIEWS_INFOBARS_INFOBAR_CONTAINER_H_ +#define CHROME_BROWSER_VIEWS_INFOBARS_INFOBAR_CONTAINER_H_ + +#include "chrome/common/notification_service.h" +#include "chrome/views/view.h" + +class BrowserView; +class InfoBarDelegate; +class TabContents; + +// A views::View subclass that contains a collection of InfoBars associated with +// a TabContents. +class InfoBarContainer : public views::View, + public NotificationObserver { + public: + explicit InfoBarContainer(BrowserView* browser_view); + virtual ~InfoBarContainer(); + + // Changes the TabContents for which this container is showing InfoBars. Can + // be NULL. + void ChangeTabContents(TabContents* contents); + + // Called by child InfoBars as they animate. If |completed| is true, the + // animation has finished running. + void InfoBarAnimated(bool completed); + + // Remove the specified InfoBarDelegate from the selected TabContents. This + // will notify us back and cause us to close the View. This is called from + // the InfoBar's close button handler. + void RemoveDelegate(InfoBarDelegate* delegate); + + // Overridden from views::View: + virtual gfx::Size GetPreferredSize(); + virtual void Layout(); + protected: + virtual void ViewHierarchyChanged(bool is_add, + views::View* parent, + views::View* child); + + private: + // Overridden from NotificationObserver: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + // Constructs the InfoBars needed to reflect the state of the current + // TabContents associated with this container. No animations are run during + // this process. + 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); + + // 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); + + // The BrowserView that hosts this InfoBarContainer. + BrowserView* browser_view_; + + // The TabContents for which we are currently showing InfoBars. + TabContents* tab_contents_; + + DISALLOW_COPY_AND_ASSIGN(InfoBarContainer); +}; + +#endif // #ifndef CHROME_BROWSER_VIEWS_INFOBARS_INFOBAR_CONTAINER_H_ diff --git a/chrome/browser/views/infobars/infobars.cc b/chrome/browser/views/infobars/infobars.cc new file mode 100644 index 0000000..5733d33 --- /dev/null +++ b/chrome/browser/views/infobars/infobars.cc @@ -0,0 +1,291 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/views/infobars/infobars.h" + +#include "chrome/app/theme/theme_resources.h" +#include "chrome/browser/views/infobars/infobar_container.h" +#include "chrome/common/l10n_util.h" +#include "chrome/common/resource_bundle.h" +#include "chrome/common/slide_animation.h" +#include "chrome/views/background.h" +#include "chrome/views/button.h" +#include "chrome/views/image_view.h" +#include "chrome/views/label.h" + +#include "generated_resources.h" + +const double kInfoBarHeight = 37.0; + +static const int kVerticalPadding = 3; +static const int kHorizontalPadding = 3; +static const int kIconLabelSpacing = 5; +static const int kButtonSpacing = 5; + +static const SkColor kBackgroundColorTop = SkColorSetRGB(255, 242, 183); +static const SkColor kBackgroundColorBottom = SkColorSetRGB(250, 230, 145); + +static const int kSeparatorLineHeight = 1; +static const SkColor kSeparatorColor = SkColorSetRGB(165, 165, 165); + +namespace { +int OffsetY(views::View* parent, const gfx::Size prefsize) { + return std::max((parent->height() - prefsize.height()) / 2, 0); +} +} + +// InfoBarBackground ----------------------------------------------------------- + +class InfoBarBackground : public views::Background { + public: + InfoBarBackground() { + gradient_background_.reset( + views::Background::CreateVerticalGradientBackground( + kBackgroundColorTop, kBackgroundColorBottom)); + } + + // Overridden from views::View: + virtual void Paint(ChromeCanvas* canvas, views::View* view) const { + // First paint the gradient background. + gradient_background_->Paint(canvas, view); + + // Now paint the separator line. + canvas->FillRectInt(kSeparatorColor, 0, + view->height() - kSeparatorLineHeight, view->width(), + kSeparatorLineHeight); + } + + private: + scoped_ptr<views::Background> gradient_background_; + + DISALLOW_COPY_AND_ASSIGN(InfoBarBackground); +}; + +// InfoBar, public: ------------------------------------------------------------ + +InfoBar::InfoBar(InfoBarDelegate* delegate) + : delegate_(delegate), + close_button_(new views::Button) { + set_background(new InfoBarBackground); + + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + close_button_->SetImage(views::Button::BS_NORMAL, + rb.GetBitmapNamed(IDR_CLOSE_BAR)); + close_button_->SetImage(views::Button::BS_HOT, + rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); + close_button_->SetImage(views::Button::BS_PUSHED, + rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); + close_button_->SetListener(this, 0); + close_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE)); + AddChildView(close_button_); + + animation_.reset(new SlideAnimation(this)); + animation_->SetTweenType(SlideAnimation::NONE); +} + +InfoBar::~InfoBar() { +} + +void InfoBar::AnimateOpen() { + animation_->Show(); +} + +void InfoBar::Open() { + animation_->Reset(1.0); + animation_->Show(); +} + +void InfoBar::AnimateClose() { + animation_->Hide(); +} + +void InfoBar::Close() { + GetParent()->RemoveChildView(this); + if (delegate()) + delegate()->InfoBarClosed(); + delete this; +} + +// InfoBar, views::View overrides: --------------------------------------------- + +gfx::Size InfoBar::GetPreferredSize() { + int height = static_cast<int>(kInfoBarHeight * animation_->GetCurrentValue()); + return gfx::Size(0, height); +} + +void InfoBar::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()); + +} + +// InfoBar, protected: --------------------------------------------------------- + +int InfoBar::GetAvailableWidth() const { + return close_button_->x() - kIconLabelSpacing; +} + +// InfoBar, views::BaseButton::ButtonListener implementation: ------------------ + +void InfoBar::ButtonPressed(views::BaseButton* sender) { + if (sender == close_button_) + container_->RemoveDelegate(delegate()); +} + +// InfoBar, AnimationDelegate implementation: ---------------------------------- + +void InfoBar::AnimationProgressed(const Animation* animation) { + container_->InfoBarAnimated(true); +} + +void InfoBar::AnimationEnded(const Animation* animation) { + container_->InfoBarAnimated(false); + + if (!animation_->IsShowing()) + Close(); +} + +// AlertInfoBar, public: ------------------------------------------------------- + +AlertInfoBar::AlertInfoBar(AlertInfoBarDelegate* delegate) + : InfoBar(delegate) { + label_ = new views::Label( + delegate->GetMessageText(), + ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont)); + label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + AddChildView(label_); + + icon_ = new views::ImageView; + if (delegate->GetIcon()) + icon_->SetImage(delegate->GetIcon()); + AddChildView(icon_); +} + +AlertInfoBar::~AlertInfoBar() { + +} + +// AlertInfoBar, views::View overrides: ---------------------------------------- + +void AlertInfoBar::Layout() { + // Layout the close button. + InfoBar::Layout(); + + // Layout the icon and text. + gfx::Size icon_ps = icon_->GetPreferredSize(); + icon_->SetBounds(kHorizontalPadding, OffsetY(this, icon_ps), icon_ps.width(), + icon_ps.height()); + + gfx::Size text_ps = label_->GetPreferredSize(); + int text_width = + GetAvailableWidth() - icon_->bounds().right() - kIconLabelSpacing; + label_->SetBounds(icon_->bounds().right() + kIconLabelSpacing, + OffsetY(this, text_ps), text_width, text_ps.height()); +} + +// AlertInfoBar, private: ------------------------------------------------------ + +AlertInfoBarDelegate* AlertInfoBar::GetDelegate() { + return delegate()->AsAlertInfoBarDelegate(); +} + +// ConfirmInfoBar, public: ----------------------------------------------------- + +ConfirmInfoBar::ConfirmInfoBar(ConfirmInfoBarDelegate* delegate) + : ok_button_(NULL), + cancel_button_(NULL), + initialized_(false), + AlertInfoBar(delegate) { +} + +ConfirmInfoBar::~ConfirmInfoBar() { +} + +// ConfirmInfoBar, views::View overrides: -------------------------------------- + +void ConfirmInfoBar::Layout() { + InfoBar::Layout(); + int available_width = InfoBar::GetAvailableWidth(); + int ok_button_width = 0; + int cancel_button_width = 0; + gfx::Size ok_ps = ok_button_->GetPreferredSize(); + gfx::Size cancel_ps = cancel_button_->GetPreferredSize(); + + if (GetDelegate()->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK) + ok_button_width = ok_ps.width(); + if (GetDelegate()->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL) + cancel_button_width = cancel_ps.width(); + + cancel_button_->SetBounds(available_width - cancel_button_width, + OffsetY(this, cancel_ps), cancel_ps.width(), + cancel_ps.height()); + int spacing = cancel_button_width > 0 ? kButtonSpacing : 0; + ok_button_->SetBounds(cancel_button_->x() - spacing - ok_button_width, + OffsetY(this, ok_ps), ok_ps.width(), ok_ps.height()); + + AlertInfoBar::Layout(); +} + +void ConfirmInfoBar::ViewHierarchyChanged(bool is_add, + views::View* parent, + views::View* child) { + if (is_add && child == this && !initialized_) { + Init(); + initialized_ = true; + } +} + +// ConfirmInfoBar, views::NativeButton::Listener implementation: --------------- + +void ConfirmInfoBar::ButtonPressed(views::NativeButton* sender) { + if (sender == ok_button_) { + GetDelegate()->Accept(); + } else if (sender == cancel_button_) { + GetDelegate()->Cancel(); + } else { + NOTREACHED(); + } +} + +// ConfirmInfoBar, InfoBar overrides: ------------------------------------------ + +int ConfirmInfoBar::GetAvailableWidth() const { + if (ok_button_) + return ok_button_->x() - kButtonSpacing; + if (cancel_button_) + return cancel_button_->x() - kButtonSpacing; + return InfoBar::GetAvailableWidth(); +} + +// ConfirmInfoBar, private: ---------------------------------------------------- + +ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() { + return delegate()->AsConfirmInfoBarDelegate(); +} + +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_); +} + +// AlertInfoBarDelegate, InfoBarDelegate overrides: ---------------------------- + +InfoBar* AlertInfoBarDelegate::CreateInfoBar() { + return new AlertInfoBar(this); +} + +// ConfirmInfoBarDelegate, InfoBarDelegate overrides: -------------------------- + +InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() { + return new ConfirmInfoBar(this); +} diff --git a/chrome/browser/views/infobars/infobars.h b/chrome/browser/views/infobars/infobars.h new file mode 100644 index 0000000..1e02f96 --- /dev/null +++ b/chrome/browser/views/infobars/infobars.h @@ -0,0 +1,138 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_VIEWS_INFOBARS_INFOBARS_H_ +#define CHROME_BROWSER_VIEWS_INFOBARS_INFOBARS_H_ + +#include "chrome/browser/infobar_delegate.h" +#include "chrome/views/base_button.h" +#include "chrome/views/native_button.h" + +class InfoBarContainer; +class SlideAnimation; +namespace views { +class Button; +class ImageView; +class Label; +} + +// This file contains implementations for some general purpose InfoBars. See +// chrome/browser/infobar_delegate.h for the delegate interface(s) that you must +// implement to use these. + +class InfoBar : public views::View, + public views::BaseButton::ButtonListener, + public AnimationDelegate { + public: + explicit InfoBar(InfoBarDelegate* delegate); + virtual ~InfoBar(); + + InfoBarDelegate* delegate() const { return delegate_; } + + void set_container(InfoBarContainer* container) { container_ = container; } + + // Starts animating the InfoBar open. + void AnimateOpen(); + + // Opens the InfoBar immediately. + void Open(); + + // Starts animating the InfoBar closed. It will not be closed until the + // animation has completed, when |Close| will be called. + void AnimateClose(); + + // Closes the InfoBar immediately and removes it from its container. Notifies + // the delegate that it has closed. The InfoBar is deleted after this function + // is called. + void Close(); + + // Overridden from views::View: + virtual gfx::Size GetPreferredSize(); + virtual void Layout(); + + protected: + // Returns the available width of the View for use by child view layout, + // excluding the close button. + virtual int GetAvailableWidth() const; + + private: + // Overridden from views::Button::ButtonListener: + virtual void ButtonPressed(views::BaseButton* sender); + + // Overridden from AnimationDelegate: + virtual void AnimationProgressed(const Animation* animation); + virtual void AnimationEnded(const Animation* animation); + + // The InfoBar's container + InfoBarContainer* container_; + + // The InfoBar's delegate. + InfoBarDelegate* delegate_; + + // The Close Button at the right edge of the InfoBar. + views::Button* close_button_; + + // The animation that runs when the InfoBar is opened or closed. + scoped_ptr<SlideAnimation> animation_; + + DISALLOW_COPY_AND_ASSIGN(InfoBar); +}; + +class AlertInfoBar : public InfoBar { + public: + explicit AlertInfoBar(AlertInfoBarDelegate* delegate); + virtual ~AlertInfoBar(); + + // Overridden from views::View: + virtual void Layout(); + + protected: + views::Label* label() const { return label_; } + views::ImageView* icon() const { return icon_; } + + private: + AlertInfoBarDelegate* GetDelegate(); + + views::Label* label_; + views::ImageView* icon_; + + DISALLOW_COPY_AND_ASSIGN(AlertInfoBar); +}; + +class ConfirmInfoBar : public AlertInfoBar, + public views::NativeButton::Listener { + public: + explicit ConfirmInfoBar(ConfirmInfoBarDelegate* delegate); + virtual ~ConfirmInfoBar(); + + // Overridden from views::View: + virtual void Layout(); + + protected: + // Overridden from views::View: + virtual void ViewHierarchyChanged(bool is_add, + views::View* parent, + views::View* child); + + // Overridden from views::NativeButton::Listener: + virtual void ButtonPressed(views::NativeButton* sender); + + // Overridden from InfoBar: + virtual int GetAvailableWidth() const; + + private: + void Init(); + + ConfirmInfoBarDelegate* GetDelegate(); + + views::NativeButton* ok_button_; + views::NativeButton* cancel_button_; + + bool initialized_; + + DISALLOW_COPY_AND_ASSIGN(ConfirmInfoBar); +}; + + +#endif // #ifndef CHROME_BROWSER_VIEWS_INFOBARS_INFOBARS_H_ |