summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/views
diff options
context:
space:
mode:
authorpkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-01 19:13:39 +0000
committerpkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-01 19:13:39 +0000
commit9cefab614bdf79e902f94bf13075b856e20ddf40 (patch)
tree3628ca90cf71da7da7a94dd026ca79c3072efa2b /chrome/browser/ui/views
parent722c251aeebd8a76142352f898903f8a2b5375d9 (diff)
downloadchromium_src-9cefab614bdf79e902f94bf13075b856e20ddf40.zip
chromium_src-9cefab614bdf79e902f94bf13075b856e20ddf40.tar.gz
chromium_src-9cefab614bdf79e902f94bf13075b856e20ddf40.tar.bz2
Layout changes for InfoBarView and subclasses:
* Lay out ConfirmInfoBar as per current UI guidelines (bug 39102) * Remove now-unnecessary dedicated autofill infobar, which implemented correct infobar layout only for autofill, since the default ConfirmInfoBar is now correct * ConfirmInfoBar: Don't create OK/Cancel buttons or link at all when not needed (bug 27832) * Add child views when the infobar is first made part of the view hierarchy rather than at construction (simplifies ownership, matches standard implementation pattern) * Translate infobars: Create language menus at construction rather than on demand (simpler code) * Elide text elements as infobar width shrinks * ...but, stop layout changes for infobar content when the infobar reaches a minimum width (i.e. don't drop buttons atop each other) * Remove now-unnecessary hardcoded 30 px. space on the right side of the ExtensionInfoBar in favor of the new and more-accurate InfoBarView::EndX() * Make ExtensionInfoBar menu animate down properly during infobar creation by calling OffsetY() instead of hardcoding a division by 2 * Remove erroneous -1s when setting ExtensionView bounds * Fix calls to InfoBarAnimated() always getting |completed| reversed BUG=27832, 39102 TEST=ConfirmInfoBars should put buttons on left by text and link on right by close button Review URL: http://codereview.chromium.org/6596058 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76406 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/ui/views')
-rw-r--r--chrome/browser/ui/views/infobars/after_translate_infobar.cc122
-rw-r--r--chrome/browser/ui/views/infobars/after_translate_infobar.h8
-rw-r--r--chrome/browser/ui/views/infobars/before_translate_infobar.cc140
-rw-r--r--chrome/browser/ui/views/infobars/before_translate_infobar.h6
-rw-r--r--chrome/browser/ui/views/infobars/confirm_infobar.cc125
-rw-r--r--chrome/browser/ui/views/infobars/confirm_infobar.h6
-rw-r--r--chrome/browser/ui/views/infobars/extension_infobar.cc79
-rw-r--r--chrome/browser/ui/views/infobars/extension_infobar.h6
-rw-r--r--chrome/browser/ui/views/infobars/infobar_container.cc12
-rw-r--r--chrome/browser/ui/views/infobars/infobar_container.h1
-rw-r--r--chrome/browser/ui/views/infobars/infobar_view.cc85
-rw-r--r--chrome/browser/ui/views/infobars/infobar_view.h10
-rw-r--r--chrome/browser/ui/views/infobars/link_infobar.cc51
-rw-r--r--chrome/browser/ui/views/infobars/link_infobar.h1
-rw-r--r--chrome/browser/ui/views/infobars/translate_infobar_base.cc35
-rw-r--r--chrome/browser/ui/views/infobars/translate_infobar_base.h3
-rw-r--r--chrome/browser/ui/views/infobars/translate_message_infobar.cc45
-rw-r--r--chrome/browser/ui/views/infobars/translate_message_infobar.h2
18 files changed, 435 insertions, 302 deletions
diff --git a/chrome/browser/ui/views/infobars/after_translate_infobar.cc b/chrome/browser/ui/views/infobars/after_translate_infobar.cc
index d9092ff..2a12950 100644
--- a/chrome/browser/ui/views/infobars/after_translate_infobar.cc
+++ b/chrome/browser/ui/views/infobars/after_translate_infobar.cc
@@ -15,41 +15,17 @@
AfterTranslateInfoBar::AfterTranslateInfoBar(
TranslateInfoBarDelegate* delegate)
: TranslateInfoBarBase(delegate),
+ label_1_(NULL),
+ label_2_(NULL),
+ label_3_(NULL),
+ original_language_menu_button_(NULL),
+ target_language_menu_button_(NULL),
+ revert_button_(NULL),
+ options_menu_button_(NULL),
original_language_menu_model_(delegate, LanguagesMenuModel::ORIGINAL),
target_language_menu_model_(delegate, LanguagesMenuModel::TARGET),
options_menu_model_(delegate),
swapped_language_buttons_(false) {
- std::vector<string16> strings;
- GetDelegate()->GetAfterTranslateStrings(&strings, &swapped_language_buttons_);
- DCHECK_EQ(3U, strings.size());
-
- label_1_ = CreateLabel(strings[0]);
- AddChildView(label_1_);
-
- original_language_menu_button_ = CreateMenuButton(string16(), true, this);
- target_language_menu_button_ = CreateMenuButton(string16(), true, this);
- AddChildView(swapped_language_buttons_ ?
- target_language_menu_button_ : original_language_menu_button_);
-
- label_2_ = CreateLabel(strings[1]);
- AddChildView(label_2_);
-
- AddChildView(swapped_language_buttons_ ?
- original_language_menu_button_ : target_language_menu_button_);
-
- label_3_ = CreateLabel(strings[2]);
- AddChildView(label_3_);
-
- revert_button_ = CreateTextButton(this,
- l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_REVERT), false);
- AddChildView(revert_button_);
-
- options_menu_button_ = CreateMenuButton(
- l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_OPTIONS), false, this);
- AddChildView(options_menu_button_);
-
- OriginalLanguageChanged();
- TargetLanguageChanged();
}
AfterTranslateInfoBar::~AfterTranslateInfoBar() {
@@ -58,10 +34,11 @@ AfterTranslateInfoBar::~AfterTranslateInfoBar() {
void AfterTranslateInfoBar::Layout() {
TranslateInfoBarBase::Layout();
- int available_width = GetAvailableWidth();
+ int available_width = std::max(0, EndX() - StartX() - ContentMinimumWidth());
gfx::Size label_1_size = label_1_->GetPreferredSize();
label_1_->SetBounds(StartX(), OffsetY(this, label_1_size),
- label_1_size.width(), label_1_size.height());
+ std::min(label_1_size.width(), available_width), label_1_size.height());
+ available_width = std::max(0, available_width - label_1_size.width());
views::MenuButton* first_button = original_language_menu_button_;
views::MenuButton* second_button = target_language_menu_button_;
@@ -74,7 +51,9 @@ void AfterTranslateInfoBar::Layout() {
gfx::Size label_2_size = label_2_->GetPreferredSize();
label_2_->SetBounds(first_button->bounds().right() + kButtonInLabelSpacing,
- OffsetY(this, label_2_size), label_2_size.width(), label_2_size.height());
+ OffsetY(this, label_2_size),
+ std::min(label_2_size.width(), available_width), label_2_size.height());
+ available_width = std::max(0, available_width - label_2_size.width());
gfx::Size second_button_size = second_button->GetPreferredSize();
second_button->SetBounds(label_2_->bounds().right() + kButtonInLabelSpacing,
@@ -83,7 +62,8 @@ void AfterTranslateInfoBar::Layout() {
gfx::Size label_3_size = label_3_->GetPreferredSize();
label_3_->SetBounds(second_button->bounds().right() + kButtonInLabelSpacing,
- OffsetY(this, label_3_size), label_3_size.width(), label_3_size.height());
+ OffsetY(this, label_3_size),
+ std::min(label_3_size.width(), available_width), label_3_size.height());
gfx::Size revert_button_size = revert_button_->GetPreferredSize();
revert_button_->SetBounds(label_3_->bounds().right() + kButtonInLabelSpacing,
@@ -91,10 +71,58 @@ void AfterTranslateInfoBar::Layout() {
revert_button_size.width(), revert_button_size.height());
gfx::Size options_size = options_menu_button_->GetPreferredSize();
- options_menu_button_->SetBounds(available_width - options_size.width(),
+ options_menu_button_->SetBounds(EndX() - options_size.width(),
OffsetY(this, options_size), options_size.width(), options_size.height());
}
+void AfterTranslateInfoBar::ViewHierarchyChanged(bool is_add,
+ View* parent,
+ View* child) {
+ if (!is_add || (child != this) || (label_1_ != NULL)) {
+ TranslateInfoBarBase::ViewHierarchyChanged(is_add, parent, child);
+ return;
+ }
+
+ std::vector<string16> strings;
+ GetDelegate()->GetAfterTranslateStrings(&strings, &swapped_language_buttons_);
+ DCHECK_EQ(3U, strings.size());
+
+ label_1_ = CreateLabel(strings[0]);
+ AddChildView(label_1_);
+
+ original_language_menu_button_ = CreateMenuButton(string16(), true, this);
+ target_language_menu_button_ = CreateMenuButton(string16(), true, this);
+ AddChildView(swapped_language_buttons_ ?
+ target_language_menu_button_ : original_language_menu_button_);
+
+ label_2_ = CreateLabel(strings[1]);
+ AddChildView(label_2_);
+
+ AddChildView(swapped_language_buttons_ ?
+ original_language_menu_button_ : target_language_menu_button_);
+
+ label_3_ = CreateLabel(strings[2]);
+ AddChildView(label_3_);
+
+ revert_button_ = CreateTextButton(this,
+ l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_REVERT), false);
+ AddChildView(revert_button_);
+
+ options_menu_button_ = CreateMenuButton(
+ l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_OPTIONS), false, this);
+ AddChildView(options_menu_button_);
+
+ // This must happen after adding all other children so InfoBarView can ensure
+ // the close button is the last child.
+ TranslateInfoBarBase::ViewHierarchyChanged(is_add, parent, child);
+
+ // These must happen after adding all children because they trigger layout,
+ // which assumes that particular children (e.g. the close button) have already
+ // been added.
+ OriginalLanguageChanged();
+ TargetLanguageChanged();
+}
+
void AfterTranslateInfoBar::ButtonPressed(views::Button* sender,
const views::Event& event) {
if (sender == revert_button_)
@@ -103,6 +131,18 @@ void AfterTranslateInfoBar::ButtonPressed(views::Button* sender,
TranslateInfoBarBase::ButtonPressed(sender, event);
}
+int AfterTranslateInfoBar::ContentMinimumWidth() const {
+ return
+ (kButtonInLabelSpacing +
+ original_language_menu_button_->GetPreferredSize().width() +
+ kButtonInLabelSpacing) +
+ (kButtonInLabelSpacing +
+ target_language_menu_button_->GetPreferredSize().width() +
+ kButtonInLabelSpacing) +
+ (kButtonInLabelSpacing + revert_button_->GetPreferredSize().width()) +
+ (kEndOfLabelSpacing + options_menu_button_->GetPreferredSize().width());
+}
+
void AfterTranslateInfoBar::OriginalLanguageChanged() {
UpdateLanguageButtonText(original_language_menu_button_,
LanguagesMenuModel::ORIGINAL);
@@ -115,21 +155,11 @@ void AfterTranslateInfoBar::TargetLanguageChanged() {
void AfterTranslateInfoBar::RunMenu(View* source, const gfx::Point& pt) {
if (source == original_language_menu_button_) {
- if (!original_language_menu_.get()) {
- original_language_menu_.reset(
- new views::Menu2(&original_language_menu_model_));
- }
original_language_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT);
} else if (source == target_language_menu_button_) {
- if (!target_language_menu_.get()) {
- target_language_menu_.reset(
- new views::Menu2(&target_language_menu_model_));
- }
target_language_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT);
} else {
DCHECK_EQ(options_menu_button_, source);
- if (!options_menu_.get())
- options_menu_.reset(new views::Menu2(&options_menu_model_));
options_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT);
}
}
diff --git a/chrome/browser/ui/views/infobars/after_translate_infobar.h b/chrome/browser/ui/views/infobars/after_translate_infobar.h
index 8dc53bf..c1cd254 100644
--- a/chrome/browser/ui/views/infobars/after_translate_infobar.h
+++ b/chrome/browser/ui/views/infobars/after_translate_infobar.h
@@ -27,7 +27,9 @@ class AfterTranslateInfoBar : public TranslateInfoBarBase,
// TranslateInfoBarBase:
virtual void Layout();
+ virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
virtual void ButtonPressed(views::Button* sender, const views::Event& event);
+ virtual int ContentMinimumWidth() const;
virtual void OriginalLanguageChanged();
virtual void TargetLanguageChanged();
@@ -47,14 +49,14 @@ class AfterTranslateInfoBar : public TranslateInfoBarBase,
views::TextButton* revert_button_;
views::MenuButton* options_menu_button_;
- scoped_ptr<views::Menu2> original_language_menu_;
LanguagesMenuModel original_language_menu_model_;
+ scoped_ptr<views::Menu2> original_language_menu_;
- scoped_ptr<views::Menu2> target_language_menu_;
LanguagesMenuModel target_language_menu_model_;
+ scoped_ptr<views::Menu2> target_language_menu_;
- scoped_ptr<views::Menu2> options_menu_;
OptionsMenuModel options_menu_model_;
+ scoped_ptr<views::Menu2> options_menu_;
// True if the target language comes before the original one.
bool swapped_language_buttons_;
diff --git a/chrome/browser/ui/views/infobars/before_translate_infobar.cc b/chrome/browser/ui/views/infobars/before_translate_infobar.cc
index b3b5f06..303b1fe 100644
--- a/chrome/browser/ui/views/infobars/before_translate_infobar.cc
+++ b/chrome/browser/ui/views/infobars/before_translate_infobar.cc
@@ -15,51 +15,18 @@
BeforeTranslateInfoBar::BeforeTranslateInfoBar(
TranslateInfoBarDelegate* delegate)
: TranslateInfoBarBase(delegate),
+ label_1_(NULL),
+ label_2_(NULL),
+ language_menu_button_(NULL),
+ accept_button_(NULL),
+ deny_button_(NULL),
never_translate_button_(NULL),
always_translate_button_(NULL),
+ options_menu_button_(NULL),
languages_menu_model_(delegate, LanguagesMenuModel::ORIGINAL),
- options_menu_model_(delegate) {
- size_t offset = 0;
- string16 text(l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_BEFORE_MESSAGE,
- string16(), &offset));
-
- label_1_ = CreateLabel(text.substr(0, offset));
- AddChildView(label_1_);
-
- language_menu_button_ = CreateMenuButton(string16(), true, this);
- AddChildView(language_menu_button_);
-
- label_2_ = CreateLabel(text.substr(offset));
- AddChildView(label_2_);
-
- accept_button_ = CreateTextButton(this,
- l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_ACCEPT), false);
- AddChildView(accept_button_);
-
- deny_button_ = CreateTextButton(this,
- l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_DENY), false);
- AddChildView(deny_button_);
-
- const string16& language(delegate->GetLanguageDisplayableNameAt(
- delegate->original_language_index()));
- if (delegate->ShouldShowNeverTranslateButton()) {
- DCHECK(!delegate->ShouldShowAlwaysTranslateButton());
- never_translate_button_ = CreateTextButton(this,
- l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_NEVER_TRANSLATE,
- language), false);
- AddChildView(never_translate_button_);
- } else if (delegate->ShouldShowAlwaysTranslateButton()) {
- always_translate_button_ = CreateTextButton(this,
- l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_ALWAYS_TRANSLATE,
- language), false);
- AddChildView(always_translate_button_);
- }
-
- options_menu_button_ = CreateMenuButton(
- l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_OPTIONS), false, this);
- AddChildView(options_menu_button_);
-
- OriginalLanguageChanged();
+ languages_menu_(new views::Menu2(&languages_menu_model_)),
+ options_menu_model_(delegate),
+ options_menu_(new views::Menu2(&options_menu_model_)) {
}
BeforeTranslateInfoBar::~BeforeTranslateInfoBar() {
@@ -68,10 +35,11 @@ BeforeTranslateInfoBar::~BeforeTranslateInfoBar() {
void BeforeTranslateInfoBar::Layout() {
TranslateInfoBarBase::Layout();
- int available_width = GetAvailableWidth();
+ int available_width = std::max(0, EndX() - StartX() - ContentMinimumWidth());
gfx::Size label_1_size = label_1_->GetPreferredSize();
label_1_->SetBounds(StartX(), OffsetY(this, label_1_size),
- label_1_size.width(), label_1_size.height());
+ std::min(label_1_size.width(), available_width), label_1_size.height());
+ available_width = std::max(0, available_width - label_1_size.width());
gfx::Size language_button_size = language_menu_button_->GetPreferredSize();
language_menu_button_->SetBounds(
@@ -82,7 +50,8 @@ void BeforeTranslateInfoBar::Layout() {
gfx::Size label_2_size = label_2_->GetPreferredSize();
label_2_->SetBounds(
language_menu_button_->bounds().right() + kButtonInLabelSpacing,
- OffsetY(this, label_2_size), label_2_size.width(), label_2_size.height());
+ OffsetY(this, label_2_size),
+ std::min(label_2_size.width(), available_width), label_2_size.height());
gfx::Size accept_button_size = accept_button_->GetPreferredSize();
accept_button_->SetBounds(label_2_->bounds().right() + kEndOfLabelSpacing,
@@ -112,10 +81,85 @@ void BeforeTranslateInfoBar::Layout() {
}
gfx::Size options_size = options_menu_button_->GetPreferredSize();
- options_menu_button_->SetBounds(available_width - options_size.width(),
+ options_menu_button_->SetBounds(EndX() - options_size.width(),
OffsetY(this, options_size), options_size.width(), options_size.height());
}
+void BeforeTranslateInfoBar::ViewHierarchyChanged(bool is_add,
+ View* parent,
+ View* child) {
+ if (!is_add || (child != this) || (label_1_ != NULL)) {
+ TranslateInfoBarBase::ViewHierarchyChanged(is_add, parent, child);
+ return;
+ }
+
+ size_t offset = 0;
+ string16 text(l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_BEFORE_MESSAGE,
+ string16(), &offset));
+
+ label_1_ = CreateLabel(text.substr(0, offset));
+ AddChildView(label_1_);
+
+ language_menu_button_ = CreateMenuButton(string16(), true, this);
+ AddChildView(language_menu_button_);
+
+ label_2_ = CreateLabel(text.substr(offset));
+ AddChildView(label_2_);
+
+ accept_button_ = CreateTextButton(this,
+ l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_ACCEPT), false);
+ AddChildView(accept_button_);
+
+ deny_button_ = CreateTextButton(this,
+ l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_DENY), false);
+ AddChildView(deny_button_);
+
+ TranslateInfoBarDelegate* delegate = GetDelegate();
+ const string16& language(delegate->GetLanguageDisplayableNameAt(
+ delegate->original_language_index()));
+ if (delegate->ShouldShowNeverTranslateButton()) {
+ DCHECK(!delegate->ShouldShowAlwaysTranslateButton());
+ never_translate_button_ = CreateTextButton(this,
+ l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_NEVER_TRANSLATE,
+ language), false);
+ AddChildView(never_translate_button_);
+ } else if (delegate->ShouldShowAlwaysTranslateButton()) {
+ always_translate_button_ = CreateTextButton(this,
+ l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_ALWAYS_TRANSLATE,
+ language), false);
+ AddChildView(always_translate_button_);
+ }
+
+ options_menu_button_ = CreateMenuButton(
+ l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_OPTIONS), false, this);
+ AddChildView(options_menu_button_);
+
+ // This must happen after adding all other children so InfoBarView can ensure
+ // the close button is the last child.
+ TranslateInfoBarBase::ViewHierarchyChanged(is_add, parent, child);
+
+ // This must happen after adding all children because it triggers layout,
+ // which assumes that particular children (e.g. the close button) have already
+ // been added.
+ OriginalLanguageChanged();
+}
+
+int BeforeTranslateInfoBar::ContentMinimumWidth() const {
+ return
+ (kButtonInLabelSpacing +
+ language_menu_button_->GetPreferredSize().width() +
+ kButtonInLabelSpacing) +
+ (kEndOfLabelSpacing + accept_button_->GetPreferredSize().width()) +
+ (kButtonButtonSpacing + deny_button_->GetPreferredSize().width()) +
+ ((never_translate_button_ == NULL) ? 0 :
+ (kButtonButtonSpacing +
+ never_translate_button_->GetPreferredSize().width())) +
+ ((always_translate_button_ == NULL) ? 0 :
+ (kButtonButtonSpacing +
+ always_translate_button_->GetPreferredSize().width())) +
+ (kEndOfLabelSpacing + options_menu_button_->GetPreferredSize().width());
+}
+
void BeforeTranslateInfoBar::ButtonPressed(views::Button* sender,
const views::Event& event) {
TranslateInfoBarDelegate* delegate = GetDelegate();
@@ -139,13 +183,9 @@ void BeforeTranslateInfoBar::OriginalLanguageChanged() {
void BeforeTranslateInfoBar::RunMenu(View* source, const gfx::Point& pt) {
if (source == language_menu_button_) {
- if (!languages_menu_.get())
- languages_menu_.reset(new views::Menu2(&languages_menu_model_));
languages_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT);
} else {
DCHECK_EQ(options_menu_button_, source);
- if (!options_menu_.get())
- options_menu_.reset(new views::Menu2(&options_menu_model_));
options_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT);
}
}
diff --git a/chrome/browser/ui/views/infobars/before_translate_infobar.h b/chrome/browser/ui/views/infobars/before_translate_infobar.h
index efe8dc7..546b33f 100644
--- a/chrome/browser/ui/views/infobars/before_translate_infobar.h
+++ b/chrome/browser/ui/views/infobars/before_translate_infobar.h
@@ -28,6 +28,8 @@ class BeforeTranslateInfoBar : public TranslateInfoBarBase,
// TranslateInfoBarBase:
virtual void Layout();
virtual void ButtonPressed(views::Button* sender, const views::Event& event);
+ virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
+ virtual int ContentMinimumWidth() const;
virtual void OriginalLanguageChanged();
// views::ViewMenuDelegate:
@@ -47,11 +49,11 @@ class BeforeTranslateInfoBar : public TranslateInfoBarBase,
views::TextButton* always_translate_button_;
views::MenuButton* options_menu_button_;
- scoped_ptr<views::Menu2> languages_menu_;
LanguagesMenuModel languages_menu_model_;
+ scoped_ptr<views::Menu2> languages_menu_;
- scoped_ptr<views::Menu2> options_menu_;
OptionsMenuModel options_menu_model_;
+ scoped_ptr<views::Menu2> options_menu_;
DISALLOW_COPY_AND_ASSIGN(BeforeTranslateInfoBar);
};
diff --git a/chrome/browser/ui/views/infobars/confirm_infobar.cc b/chrome/browser/ui/views/infobars/confirm_infobar.cc
index d4ae788..d190cfc 100644
--- a/chrome/browser/ui/views/infobars/confirm_infobar.cc
+++ b/chrome/browser/ui/views/infobars/confirm_infobar.cc
@@ -19,80 +19,73 @@ InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() {
ConfirmInfoBar::ConfirmInfoBar(ConfirmInfoBarDelegate* delegate)
: InfoBarView(delegate),
- initialized_(false) {
- label_ = CreateLabel(delegate->GetMessageText());
-
- ok_button_ = CreateTextButton(this,
- (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK) ?
- delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK) :
- string16(),
- delegate->NeedElevation(ConfirmInfoBarDelegate::BUTTON_OK));
- cancel_button_ = CreateTextButton(this,
- (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL) ?
- delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL) :
- string16(),
- delegate->NeedElevation(ConfirmInfoBarDelegate::BUTTON_CANCEL));
-
- link_ = CreateLink(delegate->GetLinkText(), this, background()->get_color());
+ label_(NULL),
+ ok_button_(NULL),
+ cancel_button_(NULL),
+ link_(NULL) {
}
ConfirmInfoBar::~ConfirmInfoBar() {
- if (!initialized_) {
- delete label_;
- delete ok_button_;
- delete cancel_button_;
- delete link_;
- }
}
void ConfirmInfoBar::Layout() {
InfoBarView::Layout();
- int available_width = InfoBarView::GetAvailableWidth();
- int ok_button_width = 0;
- int cancel_button_width = 0;
- gfx::Size ok_size = ok_button_->GetPreferredSize();
- gfx::Size cancel_size = cancel_button_->GetPreferredSize();
-
- if (GetDelegate()->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK) {
- ok_button_width = ok_size.width();
- } else {
- ok_button_->SetVisible(false);
- }
- if (GetDelegate()->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL) {
- cancel_button_width = cancel_size.width();
- } else {
- cancel_button_->SetVisible(false);
- }
-
- cancel_button_->SetBounds(available_width - cancel_button_width,
- OffsetY(this, cancel_size), cancel_size.width(), cancel_size.height());
- int spacing = cancel_button_width > 0 ? kButtonButtonSpacing : 0;
- ok_button_->SetBounds(cancel_button_->x() - spacing - ok_button_width,
- OffsetY(this, ok_size), ok_size.width(), ok_size.height());
-
+ int available_width = std::max(0, EndX() - StartX() - ContentMinimumWidth());
gfx::Size label_size = label_->GetPreferredSize();
label_->SetBounds(StartX(), OffsetY(this, label_size),
std::min(label_size.width(), available_width), label_size.height());
+ available_width = std::max(0, available_width - label_size.width());
+
+ int button_x = label_->bounds().right() + kEndOfLabelSpacing;
+ if (ok_button_ != NULL) {
+ gfx::Size ok_size = ok_button_->GetPreferredSize();
+ ok_button_->SetBounds(button_x, OffsetY(this, ok_size), ok_size.width(),
+ ok_size.height());
+ button_x += ok_size.width() + kButtonButtonSpacing;
+ }
- // Now append the link to the label's right edge.
- link_->SetVisible(!link_->GetText().empty());
- gfx::Size link_size = link_->GetPreferredSize();
- int link_x = label_->bounds().right() + kEndOfLabelSpacing;
- int link_w = std::min(GetAvailableWidth() - link_x, link_size.width());
- link_->SetBounds(link_x, OffsetY(this, link_size), link_w,
- link_size.height());
+ if (cancel_button_ != NULL) {
+ gfx::Size cancel_size = cancel_button_->GetPreferredSize();
+ cancel_button_->SetBounds(button_x, OffsetY(this, cancel_size),
+ cancel_size.width(), cancel_size.height());
+ }
+
+ if (link_ != NULL) {
+ gfx::Size link_size = link_->GetPreferredSize();
+ int link_width = std::min(link_size.width(), available_width);
+ link_->SetBounds(EndX() - link_width, OffsetY(this, link_size), link_width,
+ link_size.height());
+ }
}
void ConfirmInfoBar::ViewHierarchyChanged(bool is_add,
View* parent,
View* child) {
- if (is_add && child == this && !initialized_) {
+ if (is_add && child == this && (label_ == NULL)) {
+ ConfirmInfoBarDelegate* delegate = GetDelegate();
+ label_ = CreateLabel(delegate->GetMessageText());
AddChildView(label_);
- AddChildView(ok_button_);
- AddChildView(cancel_button_);
- AddChildView(link_);
- initialized_ = true;
+
+ if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK) {
+ ok_button_ = CreateTextButton(this,
+ delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK),
+ delegate->NeedElevation(ConfirmInfoBarDelegate::BUTTON_OK));
+ AddChildView(ok_button_);
+ }
+
+ if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL) {
+ cancel_button_ = CreateTextButton(this,
+ delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL),
+ delegate->NeedElevation(ConfirmInfoBarDelegate::BUTTON_CANCEL));
+ AddChildView(cancel_button_);
+ }
+
+ string16 link_text(delegate->GetLinkText());
+ if (!link_text.empty()) {
+ link_ = CreateLink(link_text, this, background()->get_color());
+ AddChildView(link_);
+ }
}
// This must happen after adding all other children so InfoBarView can ensure
@@ -100,17 +93,13 @@ void ConfirmInfoBar::ViewHierarchyChanged(bool is_add,
InfoBarView::ViewHierarchyChanged(is_add, parent, child);
}
-int ConfirmInfoBar::GetAvailableWidth() const {
- return ok_button_->x() - kEndOfLabelSpacing;
-}
-
void ConfirmInfoBar::ButtonPressed(views::Button* sender,
const views::Event& event) {
ConfirmInfoBarDelegate* delegate = GetDelegate();
- if (sender == ok_button_) {
+ if ((ok_button_ != NULL) && sender == ok_button_) {
if (delegate->Accept())
RemoveInfoBar();
- } else if (sender == cancel_button_) {
+ } else if ((cancel_button_ != NULL) && (sender == cancel_button_)) {
if (delegate->Cancel())
RemoveInfoBar();
} else {
@@ -118,7 +107,19 @@ void ConfirmInfoBar::ButtonPressed(views::Button* sender,
}
}
+int ConfirmInfoBar::ContentMinimumWidth() const {
+ int width = (link_ == NULL) ? 0 : kEndOfLabelSpacing; // Space before link
+ int before_cancel_spacing = kEndOfLabelSpacing;
+ if (ok_button_ != NULL) {
+ width += kEndOfLabelSpacing + ok_button_->GetPreferredSize().width();
+ before_cancel_spacing = kButtonButtonSpacing;
+ }
+ return width + ((cancel_button_ == NULL) ? 0 :
+ (before_cancel_spacing + cancel_button_->GetPreferredSize().width()));
+}
+
void ConfirmInfoBar::LinkActivated(views::Link* source, int event_flags) {
+ DCHECK(link_ != NULL);
DCHECK_EQ(link_, source);
if (GetDelegate()->LinkClicked(
event_utils::DispositionFromEventFlags(event_flags)))
diff --git a/chrome/browser/ui/views/infobars/confirm_infobar.h b/chrome/browser/ui/views/infobars/confirm_infobar.h
index be99c68..9ba0055 100644
--- a/chrome/browser/ui/views/infobars/confirm_infobar.h
+++ b/chrome/browser/ui/views/infobars/confirm_infobar.h
@@ -18,8 +18,6 @@ class TextButton;
// An infobar that shows a message, up to two optional buttons, and an optional,
// right-aligned link. This is commonly used to do things like:
// "Would you like to do X? [Yes] [No] _Learn More_ [x]"
-// TODO(pkasting): The above layout is the desired, but not current, layout; fix
-// coming in a future patch.
class ConfirmInfoBar : public InfoBarView,
public views::LinkController {
public:
@@ -31,8 +29,8 @@ class ConfirmInfoBar : public InfoBarView,
// InfoBarView:
virtual void Layout();
virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
- virtual int GetAvailableWidth() const;
virtual void ButtonPressed(views::Button* sender, const views::Event& event);
+ virtual int ContentMinimumWidth() const;
// views::LinkController:
virtual void LinkActivated(views::Link* source, int event_flags);
@@ -44,8 +42,6 @@ class ConfirmInfoBar : public InfoBarView,
views::TextButton* cancel_button_;
views::Link* link_;
- bool initialized_;
-
DISALLOW_COPY_AND_ASSIGN(ConfirmInfoBar);
};
diff --git a/chrome/browser/ui/views/infobars/extension_infobar.cc b/chrome/browser/ui/views/infobars/extension_infobar.cc
index 7d5a404..0d26942 100644
--- a/chrome/browser/ui/views/infobars/extension_infobar.cc
+++ b/chrome/browser/ui/views/infobars/extension_infobar.cc
@@ -32,15 +32,12 @@ InfoBar* ExtensionInfoBarDelegate::CreateInfoBar() {
namespace {
// The horizontal margin between the menu and the Extension (HTML) view.
static const int kMenuHorizontalMargin = 1;
-
-// The amount of space to the right of the Extension (HTML) view (to avoid
-// overlapping the close button for the InfoBar).
-static const int kFarRightMargin = 30;
};
ExtensionInfoBar::ExtensionInfoBar(ExtensionInfoBarDelegate* delegate)
: InfoBarView(delegate),
delegate_(delegate),
+ menu_(NULL),
ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)) {
delegate->set_observer(this);
@@ -49,15 +46,8 @@ ExtensionInfoBar::ExtensionInfoBar(ExtensionInfoBarDelegate* delegate)
set_target_height((height > 0) ?
(height + InfoBarBackground::kSeparatorLineHeight) : height);
- // Setup the extension icon and its associated drop down menu.
- SetupIconAndMenu();
-
// Get notified of resize events for the ExtensionView.
extension_view->SetContainer(this);
- // We show the ExtensionView, but we don't want it deleted when we get
- // destroyed, which happens on tab switching (for example).
- extension_view->set_parent_owned(false);
- AddChildView(extension_view);
}
ExtensionInfoBar::~ExtensionInfoBar() {
@@ -71,12 +61,54 @@ void ExtensionInfoBar::Layout() {
InfoBarView::Layout();
gfx::Size menu_size = menu_->GetPreferredSize();
- menu_->SetBounds(0, (height() - menu_size.height()) / 2, menu_size.width(),
+ menu_->SetBounds(StartX(), OffsetY(this, menu_size), menu_size.width(),
menu_size.height());
- int x = menu_->bounds().right() + kMenuHorizontalMargin;
- GetDelegate()->extension_host()->view()->SetBounds(x, 0,
- width() - x - kFarRightMargin - 1, height() - 1);
+ GetDelegate()->extension_host()->view()->SetBounds(
+ menu_->bounds().right() + kMenuHorizontalMargin, 0,
+ std::max(0, EndX() - StartX() - ContentMinimumWidth()), height());
+}
+
+void ExtensionInfoBar::ViewHierarchyChanged(bool is_add,
+ View* parent,
+ View* child) {
+ if (!is_add || (child != this) || (menu_ != NULL)) {
+ InfoBarView::ViewHierarchyChanged(is_add, parent, child);
+ return;
+ }
+
+ menu_ = new views::MenuButton(NULL, std::wstring(), this, false);
+ menu_->SetVisible(false);
+ AddChildView(menu_);
+
+ ExtensionHost* extension_host = GetDelegate()->extension_host();
+ ExtensionView* extension_view = extension_host->view();
+ // We show the ExtensionView, but we don't want it deleted when we get
+ // destroyed, which happens on tab switching (for example).
+ extension_view->set_parent_owned(false);
+ AddChildView(extension_view);
+
+ // This must happen after adding all other children so InfoBarView can ensure
+ // the close button is the last child.
+ InfoBarView::ViewHierarchyChanged(is_add, parent, child);
+
+ // This must happen after adding all children because it can trigger layout,
+ // which assumes that particular children (e.g. the close button) have already
+ // been added.
+ const Extension* extension = extension_host->extension();
+ int image_size = Extension::EXTENSION_ICON_BITTY;
+ ExtensionResource icon_resource = extension->GetIconResource(
+ image_size, ExtensionIconSet::MATCH_EXACTLY);
+ if (!icon_resource.relative_path().empty()) {
+ tracker_.LoadImage(extension, icon_resource,
+ gfx::Size(image_size, image_size), ImageLoadingTracker::DONT_CACHE);
+ } else {
+ OnImageLoaded(NULL, icon_resource, 0);
+ }
+}
+
+int ExtensionInfoBar::ContentMinimumWidth() const {
+ return menu_->GetPreferredSize().width() + kMenuHorizontalMargin;
}
void ExtensionInfoBar::OnExtensionMouseMove(ExtensionView* view) {
@@ -160,23 +192,6 @@ void ExtensionInfoBar::RunMenu(View* source, const gfx::Point& pt) {
options_menu_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPLEFT);
}
-void ExtensionInfoBar::SetupIconAndMenu() {
- menu_ = new views::MenuButton(NULL, std::wstring(), this, false);
- menu_->SetVisible(false);
- AddChildView(menu_);
-
- const Extension* extension = GetDelegate()->extension_host()->extension();
- int image_size = Extension::EXTENSION_ICON_BITTY;
- ExtensionResource icon_resource = extension->GetIconResource(
- image_size, ExtensionIconSet::MATCH_EXACTLY);
- if (!icon_resource.relative_path().empty()) {
- tracker_.LoadImage(extension, icon_resource,
- gfx::Size(image_size, image_size), ImageLoadingTracker::DONT_CACHE);
- } else {
- OnImageLoaded(NULL, icon_resource, 0);
- }
-}
-
ExtensionInfoBarDelegate* ExtensionInfoBar::GetDelegate() {
return delegate_ ? delegate_->AsExtensionInfoBarDelegate() : NULL;
}
diff --git a/chrome/browser/ui/views/infobars/extension_infobar.h b/chrome/browser/ui/views/infobars/extension_infobar.h
index 9a7068a..fe87fe3 100644
--- a/chrome/browser/ui/views/infobars/extension_infobar.h
+++ b/chrome/browser/ui/views/infobars/extension_infobar.h
@@ -32,6 +32,8 @@ class ExtensionInfoBar : public InfoBarView,
// InfoBarView:
virtual void Layout();
+ virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
+ virtual int ContentMinimumWidth() const;
// ExtensionView::Container:
virtual void OnExtensionMouseMove(ExtensionView* view);
@@ -49,10 +51,6 @@ class ExtensionInfoBar : public InfoBarView,
// views::ViewMenuDelegate:
virtual void RunMenu(View* source, const gfx::Point& pt);
- // Setup the menu button showing the small extension icon and its dropdown
- // menu.
- void SetupIconAndMenu();
-
ExtensionInfoBarDelegate* GetDelegate();
NotificationRegistrar notification_registrar_;
diff --git a/chrome/browser/ui/views/infobars/infobar_container.cc b/chrome/browser/ui/views/infobars/infobar_container.cc
index f7148f1..a5c489b 100644
--- a/chrome/browser/ui/views/infobars/infobar_container.cc
+++ b/chrome/browser/ui/views/infobars/infobar_container.cc
@@ -90,18 +90,6 @@ AccessibilityTypes::Role InfoBarContainer::GetAccessibleRole() {
return AccessibilityTypes::ROLE_GROUPING;
}
-void InfoBarContainer::ViewHierarchyChanged(bool is_add,
- View* parent,
- View* child) {
- if (parent == this && child->parent() == this) {
- if (delegate_) {
- // An InfoBar child was added or removed. Tell the delegate it needs to
- // re-layout since our preferred size will have changed.
- delegate_->InfoBarContainerSizeChanged(false);
- }
- }
-}
-
void InfoBarContainer::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
diff --git a/chrome/browser/ui/views/infobars/infobar_container.h b/chrome/browser/ui/views/infobars/infobar_container.h
index 9d03acb..9210c1b9 100644
--- a/chrome/browser/ui/views/infobars/infobar_container.h
+++ b/chrome/browser/ui/views/infobars/infobar_container.h
@@ -56,7 +56,6 @@ class InfoBarContainer : public AccessiblePaneView,
virtual gfx::Size GetPreferredSize();
virtual void Layout();
virtual AccessibilityTypes::Role GetAccessibleRole();
- virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
// NotificationObserver:
virtual void Observe(NotificationType type,
diff --git a/chrome/browser/ui/views/infobars/infobar_view.cc b/chrome/browser/ui/views/infobars/infobar_view.cc
index 09b5c8d..e125800 100644
--- a/chrome/browser/ui/views/infobars/infobar_view.cc
+++ b/chrome/browser/ui/views/infobars/infobar_view.cc
@@ -6,10 +6,10 @@
#include "base/message_loop.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/tab_contents/infobar_delegate.h"
#include "chrome/browser/ui/views/infobars/infobar_background.h"
#include "chrome/browser/ui/views/infobars/infobar_button_border.h"
#include "chrome/browser/ui/views/infobars/infobar_container.h"
-#include "chrome/browser/tab_contents/infobar_delegate.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
@@ -45,8 +45,7 @@ InfoBarView::InfoBarView(InfoBarDelegate* delegate)
: InfoBar(delegate),
delegate_(delegate),
icon_(NULL),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- close_button_(new views::ImageButton(this))),
+ close_button_(NULL),
ALLOW_THIS_IN_INITIALIZER_LIST(delete_factory_(this)),
target_height_(kDefaultTargetHeight) {
set_parent_owned(false); // InfoBar deletes itself at the appropriate time.
@@ -57,25 +56,6 @@ InfoBarView::InfoBarView(InfoBarDelegate* delegate)
(infobar_type == InfoBarDelegate::WARNING_TYPE) ?
IDS_ACCNAME_INFOBAR_WARNING : IDS_ACCNAME_INFOBAR_PAGE_ACTION));
- SkBitmap* image = delegate->GetIcon();
- if (image) {
- icon_ = new views::ImageView;
- icon_->SetImage(image);
- AddChildView(icon_);
- }
-
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- close_button_->SetImage(views::CustomButton::BS_NORMAL,
- rb.GetBitmapNamed(IDR_CLOSE_BAR));
- close_button_->SetImage(views::CustomButton::BS_HOT,
- rb.GetBitmapNamed(IDR_CLOSE_BAR_H));
- close_button_->SetImage(views::CustomButton::BS_PUSHED,
- 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);
}
@@ -89,7 +69,7 @@ void InfoBarView::Open() {
// size.
animation_->Reset(1.0);
if (container_)
- container_->InfoBarAnimated(false);
+ container_->InfoBarAnimated(true);
}
void InfoBarView::AnimateClose() {
@@ -107,6 +87,8 @@ void InfoBarView::AnimateClose() {
void InfoBarView::Close() {
parent()->RemoveChildView(this);
+ if (container_)
+ container_->InfoBarAnimated(true);
// 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.
@@ -261,12 +243,13 @@ void InfoBarView::Layout() {
gfx::Size icon_size = icon_->GetPreferredSize();
icon_->SetBounds(start_x, OffsetY(this, icon_size), icon_size.width(),
icon_size.height());
+ start_x += icon_->bounds().right();
}
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());
+ close_button_->SetBounds(std::max(start_x + ContentMinimumWidth(),
+ width() - kHorizontalPadding - button_size.width()),
+ OffsetY(this, button_size), button_size.width(), button_size.height());
}
void InfoBarView::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
@@ -289,6 +272,28 @@ void InfoBarView::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
if (GetFocusManager())
GetFocusManager()->AddFocusChangeListener(this);
NotifyAccessibilityEvent(AccessibilityTypes::EVENT_ALERT);
+
+ if (close_button_ == NULL) {
+ SkBitmap* image = delegate_->GetIcon();
+ if (image) {
+ icon_ = new views::ImageView;
+ icon_->SetImage(image);
+ AddChildView(icon_);
+ }
+
+ close_button_ = new views::ImageButton(this);
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ close_button_->SetImage(views::CustomButton::BS_NORMAL,
+ rb.GetBitmapNamed(IDR_CLOSE_BAR));
+ close_button_->SetImage(views::CustomButton::BS_HOT,
+ rb.GetBitmapNamed(IDR_CLOSE_BAR_H));
+ close_button_->SetImage(views::CustomButton::BS_PUSHED,
+ rb.GetBitmapNamed(IDR_CLOSE_BAR_P));
+ close_button_->SetAccessibleName(
+ l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE));
+ close_button_->SetFocusable(true);
+ AddChildView(close_button_);
+ }
} else {
DestroyFocusTracker(false);
// NULL our container_ pointer so that if Animation::Stop results in
@@ -305,7 +310,7 @@ void InfoBarView::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
}
// For accessibility, ensure the close button is the last child view.
- if ((parent == this) && (child != close_button_) &&
+ if ((close_button_ != NULL) && (parent == this) && (child != close_button_) &&
(close_button_->parent() == this) &&
(GetChildViewAt(child_count() - 1) != close_button_)) {
RemoveChildView(close_button_);
@@ -324,12 +329,11 @@ void InfoBarView::ButtonPressed(views::Button* sender,
void InfoBarView::AnimationProgressed(const ui::Animation* animation) {
if (container_)
- container_->InfoBarAnimated(true);
+ container_->InfoBarAnimated(false);
}
-int InfoBarView::GetAvailableWidth() const {
- const int kCloseButtonSpacing = 12;
- return close_button_->x() - kCloseButtonSpacing - StartX();
+int InfoBarView::ContentMinimumWidth() const {
+ return 0;
}
void InfoBarView::RemoveInfoBar() const {
@@ -338,7 +342,16 @@ void InfoBarView::RemoveInfoBar() const {
}
int InfoBarView::StartX() const {
- return ((icon_ != NULL) ? icon_->bounds().right() : 0) + kHorizontalPadding;
+ // Ensure we don't return a value greater than EndX(), so children can safely
+ // set something's width to "EndX() - StartX()" without risking that being
+ // negative.
+ return std::min(EndX(),
+ ((icon_ != NULL) ? icon_->bounds().right() : 0) + kHorizontalPadding);
+}
+
+int InfoBarView::EndX() const {
+ const int kCloseButtonSpacing = 12;
+ return close_button_->x() - kCloseButtonSpacing;
}
int InfoBarView::CenterY(const gfx::Size prefsize) const {
@@ -367,12 +380,8 @@ void InfoBarView::FocusWillChange(View* focused_before, View* focused_now) {
}
void InfoBarView::AnimationEnded(const ui::Animation* animation) {
- if (container_) {
- container_->InfoBarAnimated(false);
-
- if (!animation_->IsShowing())
- Close();
- }
+ if (container_ && !animation_->IsShowing())
+ Close();
}
void InfoBarView::DestroyFocusTracker(bool restore_focus) {
diff --git a/chrome/browser/ui/views/infobars/infobar_view.h b/chrome/browser/ui/views/infobars/infobar_view.h
index bca50ac..31d3dee 100644
--- a/chrome/browser/ui/views/infobars/infobar_view.h
+++ b/chrome/browser/ui/views/infobars/infobar_view.h
@@ -116,9 +116,10 @@ class InfoBarView : public InfoBar,
// ui::AnimationDelegate:
virtual void AnimationProgressed(const ui::Animation* animation);
- // Returns the available width of the View for use by child view layout,
- // excluding the close button.
- virtual int GetAvailableWidth() const;
+ // Returns the minimum width the content (that is, everything between the icon
+ // and the close button) can be shrunk to. This is used to prevent the close
+ // button from overlapping views that cannot be shrunk any further.
+ virtual int ContentMinimumWidth() const;
// Removes our associated InfoBarDelegate from the associated TabContents.
// (Will lead to this InfoBar being closed).
@@ -128,9 +129,10 @@ class InfoBarView : public InfoBar,
ui::SlideAnimation* animation() { return animation_.get(); }
- // Returns the initial x coordinate of the usable area for subclasses to lay
+ // These return x coordinates delimiting the usable area for subclasses to lay
// out their controls.
int StartX() const;
+ int EndX() const;
// Returns a centered y-position of a control of height specified in
// |prefsize| within the standard InfoBar height. Stable during an animation.
diff --git a/chrome/browser/ui/views/infobars/link_infobar.cc b/chrome/browser/ui/views/infobars/link_infobar.cc
index 73a227b..9548b58 100644
--- a/chrome/browser/ui/views/infobars/link_infobar.cc
+++ b/chrome/browser/ui/views/infobars/link_infobar.cc
@@ -16,19 +16,10 @@ InfoBar* LinkInfoBarDelegate::CreateInfoBar() {
// LinkInfoBar ----------------------------------------------------------------
LinkInfoBar::LinkInfoBar(LinkInfoBarDelegate* delegate)
- : InfoBarView(delegate) {
- size_t offset;
- string16 message_text = delegate->GetMessageTextWithOffset(&offset);
- DCHECK_NE(string16::npos, offset);
- label_1_ = CreateLabel(message_text.substr(0, offset));
- AddChildView(label_1_);
-
- link_ = CreateLink(delegate->GetLinkText(), this,
- background()->get_color());
- AddChildView(link_);
-
- label_2_ = CreateLabel(message_text.substr(offset));
- AddChildView(label_2_);
+ : InfoBarView(delegate),
+ label_1_(NULL),
+ link_(NULL),
+ label_2_(NULL) {
}
LinkInfoBar::~LinkInfoBar() {
@@ -37,20 +28,48 @@ LinkInfoBar::~LinkInfoBar() {
void LinkInfoBar::Layout() {
InfoBarView::Layout();
+ // TODO(pkasting): This isn't perfect; there are points when we should elide a
+ // view because its subsequent view will be too small to show an ellipsis.
gfx::Size label_1_size = label_1_->GetPreferredSize();
+ int available_width = EndX() - StartX();
label_1_->SetBounds(StartX(), OffsetY(this, label_1_size),
- label_1_size.width(), label_1_size.height());
+ std::min(label_1_size.width(), available_width), label_1_size.height());
+ available_width = std::max(0, available_width - label_1_size.width());
gfx::Size link_size = link_->GetPreferredSize();
link_->SetBounds(label_1_->bounds().right(), OffsetY(this, link_size),
- link_size.width(), link_size.height());
+ std::min(link_size.width(), available_width), link_size.height());
+ available_width = std::max(0, available_width - link_size.width());
gfx::Size label_2_size = label_2_->GetPreferredSize();
label_2_->SetBounds(link_->bounds().right(), OffsetY(this, label_2_size),
- label_2_size.width(), label_2_size.height());
+ std::min(label_2_size.width(), available_width), label_2_size.height());
+}
+
+void LinkInfoBar::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
+ if (is_add && (child == this) && (label_1_ == NULL)) {
+ LinkInfoBarDelegate* delegate = GetDelegate();
+ size_t offset;
+ string16 message_text = delegate->GetMessageTextWithOffset(&offset);
+ DCHECK_NE(string16::npos, offset);
+ label_1_ = CreateLabel(message_text.substr(0, offset));
+ AddChildView(label_1_);
+
+ link_ = CreateLink(delegate->GetLinkText(), this,
+ background()->get_color());
+ AddChildView(link_);
+
+ label_2_ = CreateLabel(message_text.substr(offset));
+ AddChildView(label_2_);
+ }
+
+ // This must happen after adding all other children so InfoBarView can ensure
+ // the close button is the last child.
+ InfoBarView::ViewHierarchyChanged(is_add, parent, child);
}
void LinkInfoBar::LinkActivated(views::Link* source, int event_flags) {
+ DCHECK(link_ != NULL);
DCHECK_EQ(link_, source);
if (GetDelegate()->LinkClicked(
event_utils::DispositionFromEventFlags(event_flags)))
diff --git a/chrome/browser/ui/views/infobars/link_infobar.h b/chrome/browser/ui/views/infobars/link_infobar.h
index cb8380b..26ab7e4 100644
--- a/chrome/browser/ui/views/infobars/link_infobar.h
+++ b/chrome/browser/ui/views/infobars/link_infobar.h
@@ -25,6 +25,7 @@ class LinkInfoBar : public InfoBarView,
// views::LinkController:
virtual void LinkActivated(views::Link* source, int event_flags);
+ virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
LinkInfoBarDelegate* GetDelegate();
diff --git a/chrome/browser/ui/views/infobars/translate_infobar_base.cc b/chrome/browser/ui/views/infobars/translate_infobar_base.cc
index 5b944f1..7337098 100644
--- a/chrome/browser/ui/views/infobars/translate_infobar_base.cc
+++ b/chrome/browser/ui/views/infobars/translate_infobar_base.cc
@@ -48,23 +48,34 @@ TranslateInfoBarBase::TranslateInfoBarBase(TranslateInfoBarDelegate* delegate)
: InfoBarView(delegate),
normal_background_(InfoBarDelegate::PAGE_ACTION_TYPE),
error_background_(InfoBarDelegate::WARNING_TYPE) {
- background_color_animation_.reset(new ui::SlideAnimation(this));
- background_color_animation_->SetTweenType(ui::Tween::LINEAR);
- background_color_animation_->SetSlideDuration(500);
- TranslateInfoBarDelegate::BackgroundAnimationType animation =
- GetDelegate()->background_animation_type();
- if (animation == TranslateInfoBarDelegate::NORMAL_TO_ERROR) {
- background_color_animation_->Show();
- } else if (animation == TranslateInfoBarDelegate::ERROR_TO_NORMAL) {
- // Hide() runs the animation in reverse.
- background_color_animation_->Reset(1.0);
- background_color_animation_->Hide();
- }
}
TranslateInfoBarBase::~TranslateInfoBarBase() {
}
+void TranslateInfoBarBase::ViewHierarchyChanged(bool is_add,
+ View* parent,
+ View* child) {
+ if (is_add && (child == this) && (background_color_animation_ == NULL)) {
+ background_color_animation_.reset(new ui::SlideAnimation(this));
+ background_color_animation_->SetTweenType(ui::Tween::LINEAR);
+ background_color_animation_->SetSlideDuration(500);
+ TranslateInfoBarDelegate::BackgroundAnimationType animation =
+ GetDelegate()->background_animation_type();
+ if (animation == TranslateInfoBarDelegate::NORMAL_TO_ERROR) {
+ background_color_animation_->Show();
+ } else if (animation == TranslateInfoBarDelegate::ERROR_TO_NORMAL) {
+ // Hide() runs the animation in reverse.
+ background_color_animation_->Reset(1.0);
+ background_color_animation_->Hide();
+ }
+ }
+
+ // This must happen after adding all other children so InfoBarView can ensure
+ // the close button is the last child.
+ InfoBarView::ViewHierarchyChanged(is_add, parent, child);
+}
+
void TranslateInfoBarBase::UpdateLanguageButtonText(
views::MenuButton* button,
LanguagesMenuModel::LanguageType language_type) {
diff --git a/chrome/browser/ui/views/infobars/translate_infobar_base.h b/chrome/browser/ui/views/infobars/translate_infobar_base.h
index 145279f..11df83e 100644
--- a/chrome/browser/ui/views/infobars/translate_infobar_base.h
+++ b/chrome/browser/ui/views/infobars/translate_infobar_base.h
@@ -28,6 +28,9 @@ class TranslateInfoBarBase : public TranslateInfoBarView,
protected:
static const int kButtonInLabelSpacing;
+ // InfoBarView:
+ virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
+
// Sets the text of the provided language menu button to reflect the current
// value from the delegate.
void UpdateLanguageButtonText(views::MenuButton* button,
diff --git a/chrome/browser/ui/views/infobars/translate_message_infobar.cc b/chrome/browser/ui/views/infobars/translate_message_infobar.cc
index 1ccbefc..0fddf35 100644
--- a/chrome/browser/ui/views/infobars/translate_message_infobar.cc
+++ b/chrome/browser/ui/views/infobars/translate_message_infobar.cc
@@ -11,15 +11,8 @@
TranslateMessageInfoBar::TranslateMessageInfoBar(
TranslateInfoBarDelegate* delegate)
: TranslateInfoBarBase(delegate),
+ label_(NULL),
button_(NULL) {
- label_ = CreateLabel(delegate->GetMessageInfoBarText());
- AddChildView(label_);
-
- string16 button_text = delegate->GetMessageInfoBarButtonText();
- if (!button_text.empty()) {
- button_ = CreateTextButton(this, button_text, false);
- AddChildView(button_);
- }
}
TranslateMessageInfoBar::~TranslateMessageInfoBar() {
@@ -29,21 +22,38 @@ void TranslateMessageInfoBar::Layout() {
TranslateInfoBarBase::Layout();
gfx::Size label_size = label_->GetPreferredSize();
- int available_width = GetAvailableWidth() - StartX();
- gfx::Size button_size;
- if (button_) {
- button_size = button_->GetPreferredSize();
- available_width -= (button_size.width() + kButtonInLabelSpacing);
- }
label_->SetBounds(StartX(), OffsetY(this, label_size),
- std::min(label_size.width(), available_width), label_size.height());
+ std::min(label_size.width(),
+ std::max(0, EndX() - StartX() - ContentMinimumWidth())),
+ label_size.height());
if (button_) {
+ gfx::Size button_size = button_->GetPreferredSize();
button_->SetBounds(label_->bounds().right() + kButtonInLabelSpacing,
OffsetY(this, button_size), button_size.width(), button_size.height());
}
}
+void TranslateMessageInfoBar::ViewHierarchyChanged(bool is_add,
+ View* parent,
+ View* child) {
+ if (is_add && (child == this) && (label_ == NULL)) {
+ TranslateInfoBarDelegate* delegate = GetDelegate();
+ label_ = CreateLabel(delegate->GetMessageInfoBarText());
+ AddChildView(label_);
+
+ string16 button_text = delegate->GetMessageInfoBarButtonText();
+ if (!button_text.empty()) {
+ button_ = CreateTextButton(this, button_text, false);
+ AddChildView(button_);
+ }
+ }
+
+ // This must happen after adding all other children so InfoBarView can ensure
+ // the close button is the last child.
+ TranslateInfoBarBase::ViewHierarchyChanged(is_add, parent, child);
+}
+
void TranslateMessageInfoBar::ButtonPressed(views::Button* sender,
const views::Event& event) {
if (sender == button_)
@@ -51,3 +61,8 @@ void TranslateMessageInfoBar::ButtonPressed(views::Button* sender,
else
TranslateInfoBarBase::ButtonPressed(sender, event);
}
+
+int TranslateMessageInfoBar::ContentMinimumWidth() const {
+ return (button_ != NULL) ?
+ (button_->GetPreferredSize().width() + kButtonInLabelSpacing) : 0;
+}
diff --git a/chrome/browser/ui/views/infobars/translate_message_infobar.h b/chrome/browser/ui/views/infobars/translate_message_infobar.h
index a503df5..c6a27fe 100644
--- a/chrome/browser/ui/views/infobars/translate_message_infobar.h
+++ b/chrome/browser/ui/views/infobars/translate_message_infobar.h
@@ -17,7 +17,9 @@ class TranslateMessageInfoBar : public TranslateInfoBarBase {
// TranslateInfoBarBase:
virtual void Layout();
+ virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
virtual void ButtonPressed(views::Button* sender, const views::Event& event);
+ virtual int ContentMinimumWidth() const;
views::Label* label_;
views::TextButton* button_;