1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/views/infobars/after_translate_infobar.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/translate/translate_infobar_delegate.h"
9 #include "grit/generated_resources.h"
10 #include "ui/base/l10n/l10n_util.h"
11 #include "ui/views/controls/button/label_button.h"
12 #include "ui/views/controls/button/menu_button.h"
13 #include "ui/views/controls/label.h"
14 #include "ui/views/controls/menu/menu_item_view.h"
16 AfterTranslateInfoBar::AfterTranslateInfoBar(
17 InfoBarService* owner,
18 TranslateInfoBarDelegate* delegate)
19 : TranslateInfoBarBase(owner, delegate),
23 original_language_menu_button_(NULL),
24 target_language_menu_button_(NULL),
26 options_menu_button_(NULL),
27 options_menu_model_(delegate),
28 swapped_language_buttons_(false) {
29 autodetermined_source_language_ =
30 delegate->original_language_index() == TranslateInfoBarDelegate::kNoIndex;
33 AfterTranslateInfoBar::~AfterTranslateInfoBar() {
36 void AfterTranslateInfoBar::Layout() {
37 TranslateInfoBarBase::Layout();
39 int available_width = std::max(0, EndX() - StartX() - ContentMinimumWidth());
40 gfx::Size label_1_size = label_1_->GetPreferredSize();
41 label_1_->SetBounds(StartX(), OffsetY(label_1_size),
42 std::min(label_1_size.width(), available_width), label_1_size.height());
43 available_width = std::max(0, available_width - label_1_size.width());
45 views::MenuButton* first_button = original_language_menu_button_;
46 views::MenuButton* second_button = target_language_menu_button_;
47 if (swapped_language_buttons_ || autodetermined_source_language_)
48 std::swap(first_button, second_button);
49 gfx::Size first_button_size = first_button->GetPreferredSize();
50 first_button->SetBounds(label_1_->bounds().right() + kButtonInLabelSpacing,
51 OffsetY(first_button_size), first_button_size.width(),
52 first_button_size.height());
54 gfx::Size label_2_size = label_2_->GetPreferredSize();
55 label_2_->SetBounds(first_button->bounds().right() + kButtonInLabelSpacing,
56 OffsetY(label_2_size), std::min(label_2_size.width(), available_width),
57 label_2_size.height());
58 available_width = std::max(0, available_width - label_2_size.width());
60 if (!autodetermined_source_language_) {
61 gfx::Size second_button_size = second_button->GetPreferredSize();
62 second_button->SetBounds(label_2_->bounds().right() + kButtonInLabelSpacing,
63 OffsetY(second_button_size), second_button_size.width(),
64 second_button_size.height());
66 gfx::Size label_3_size = label_3_->GetPreferredSize();
67 label_3_->SetBounds(second_button->bounds().right() + kButtonInLabelSpacing,
68 OffsetY(label_3_size), std::min(label_3_size.width(), available_width),
69 label_3_size.height());
72 gfx::Size revert_button_size = revert_button_->GetPreferredSize();
73 revert_button_->SetBounds(
74 (label_3_ ? label_3_ : label_2_)->bounds().right() +
75 kButtonInLabelSpacing,
76 OffsetY(revert_button_size),
77 revert_button_size.width(),
78 revert_button_size.height());
80 gfx::Size options_size = options_menu_button_->GetPreferredSize();
81 options_menu_button_->SetBounds(EndX() - options_size.width(),
82 OffsetY(options_size), options_size.width(), options_size.height());
85 void AfterTranslateInfoBar::ViewHierarchyChanged(
86 const ViewHierarchyChangedDetails& details) {
87 if (!details.is_add || (details.child != this) || (label_1_ != NULL)) {
88 TranslateInfoBarBase::ViewHierarchyChanged(details);
92 std::vector<string16> strings;
93 TranslateInfoBarDelegate::GetAfterTranslateStrings(
94 &strings, &swapped_language_buttons_, autodetermined_source_language_);
95 DCHECK_EQ(autodetermined_source_language_ ? 2U : 3U, strings.size());
97 label_1_ = CreateLabel(strings[0]);
98 AddChildView(label_1_);
100 TranslateInfoBarDelegate* delegate = GetDelegate();
101 original_language_menu_button_ = CreateMenuButton(string16(), this);
102 original_language_menu_model_.reset(new TranslateLanguageMenuModel(
103 TranslateLanguageMenuModel::ORIGINAL, delegate, this,
104 original_language_menu_button_, true));
105 target_language_menu_button_ = CreateMenuButton(string16(), this);
106 target_language_menu_model_.reset(new TranslateLanguageMenuModel(
107 TranslateLanguageMenuModel::TARGET, delegate, this,
108 target_language_menu_button_, true));
109 AddChildView((swapped_language_buttons_ || autodetermined_source_language_) ?
110 target_language_menu_button_ : original_language_menu_button_);
112 label_2_ = CreateLabel(strings[1]);
113 AddChildView(label_2_);
115 if (!autodetermined_source_language_) {
116 AddChildView(swapped_language_buttons_ ?
117 original_language_menu_button_ : target_language_menu_button_);
119 label_3_ = CreateLabel(strings[2]);
120 AddChildView(label_3_);
123 revert_button_ = CreateLabelButton(this,
124 l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_REVERT), false);
125 AddChildView(revert_button_);
127 options_menu_button_ = CreateMenuButton(
128 l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_OPTIONS), this);
129 AddChildView(options_menu_button_);
131 // This must happen after adding all other children so InfoBarView can ensure
132 // the close button is the last child.
133 TranslateInfoBarBase::ViewHierarchyChanged(details);
135 // These must happen after adding all children because they trigger layout,
136 // which assumes that particular children (e.g. the close button) have already
138 if (!autodetermined_source_language_) {
139 UpdateLanguageButtonText(original_language_menu_button_,
140 delegate->language_name_at(delegate->original_language_index()));
142 UpdateLanguageButtonText(target_language_menu_button_,
143 delegate->language_name_at(delegate->target_language_index()));
146 void AfterTranslateInfoBar::ButtonPressed(views::Button* sender,
147 const ui::Event& event) {
149 return; // We're closing; don't call anything, it might access the owner.
150 if (sender == revert_button_)
151 GetDelegate()->RevertTranslation();
153 TranslateInfoBarBase::ButtonPressed(sender, event);
156 int AfterTranslateInfoBar::ContentMinimumWidth() const {
158 (kButtonInLabelSpacing +
159 original_language_menu_button_->GetPreferredSize().width() +
160 kButtonInLabelSpacing) +
161 (kButtonInLabelSpacing +
162 target_language_menu_button_->GetPreferredSize().width() +
163 kButtonInLabelSpacing) +
164 (kButtonInLabelSpacing + revert_button_->GetPreferredSize().width()) +
165 (kEndOfLabelSpacing + options_menu_button_->GetPreferredSize().width());
168 void AfterTranslateInfoBar::OnMenuButtonClicked(views::View* source,
169 const gfx::Point& point) {
171 return; // We're closing; don't call anything, it might access the owner.
172 if (source == original_language_menu_button_) {
173 RunMenuAt(original_language_menu_model_.get(),
174 original_language_menu_button_, views::MenuItemView::TOPLEFT);
175 } else if (source == target_language_menu_button_) {
176 RunMenuAt(target_language_menu_model_.get(), target_language_menu_button_,
177 views::MenuItemView::TOPLEFT);
179 DCHECK_EQ(options_menu_button_, source);
180 RunMenuAt(&options_menu_model_, options_menu_button_,
181 views::MenuItemView::TOPRIGHT);