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/options_menu_model.h"
9 #include "chrome/browser/translate/translate_infobar_delegate.h"
10 #include "chrome/browser/ui/views/infobars/translate_language_menu_model.h"
11 #include "grit/component_strings.h"
12 #include "ui/base/l10n/l10n_util.h"
13 #include "ui/views/controls/button/label_button.h"
14 #include "ui/views/controls/button/menu_button.h"
15 #include "ui/views/controls/label.h"
17 AfterTranslateInfoBar::AfterTranslateInfoBar(
18 scoped_ptr
<TranslateInfoBarDelegate
> delegate
)
19 : TranslateInfoBarBase(delegate
.Pass()),
23 original_language_menu_button_(NULL
),
24 target_language_menu_button_(NULL
),
26 options_menu_button_(NULL
),
27 swapped_language_buttons_(false) {
28 autodetermined_source_language_
=
29 GetDelegate()->original_language_index() ==
30 TranslateInfoBarDelegate::kNoIndex
;
33 AfterTranslateInfoBar::~AfterTranslateInfoBar() {
36 void AfterTranslateInfoBar::Layout() {
37 TranslateInfoBarBase::Layout();
41 labels
.push_back(label_1_
);
42 labels
.push_back(label_2_
);
43 labels
.push_back(label_3_
);
44 AssignWidths(&labels
, std::max(0, EndX() - x
- NonLabelWidth()));
46 label_1_
->SetPosition(gfx::Point(x
, OffsetY(label_1_
)));
47 if (!label_1_
->text().empty())
48 x
= label_1_
->bounds().right() + kButtonInLabelSpacing
;
50 views::MenuButton
* first_button
, * second_button
;
51 GetButtons(&first_button
, &second_button
);
52 first_button
->SetPosition(gfx::Point(x
, OffsetY(first_button
)));
53 x
= first_button
->bounds().right();
55 label_2_
->SetPosition(
56 gfx::Point(x
+ kButtonInLabelSpacing
, OffsetY(label_2_
)));
57 if (!label_2_
->text().empty())
58 x
= label_2_
->bounds().right();
60 if (!autodetermined_source_language_
) {
61 x
+= label_2_
->text().empty() ?
62 kButtonButtonSpacing
: kButtonInLabelSpacing
;
63 second_button
->SetPosition(gfx::Point(x
, OffsetY(second_button
)));
64 x
= second_button
->bounds().right();
66 label_3_
->SetPosition(
67 gfx::Point(x
+ kButtonInLabelSpacing
, OffsetY(label_3_
)));
68 if (!label_3_
->text().empty())
69 x
= label_3_
->bounds().right();
72 revert_button_
->SetPosition(
73 gfx::Point(x
+ kEndOfLabelSpacing
, OffsetY(revert_button_
)));
75 options_menu_button_
->SetPosition(gfx::Point(
76 EndX() - options_menu_button_
->width(), OffsetY(options_menu_button_
)));
79 void AfterTranslateInfoBar::ViewHierarchyChanged(
80 const ViewHierarchyChangedDetails
& details
) {
81 if (!details
.is_add
|| (details
.child
!= this) || (label_1_
!= NULL
)) {
82 TranslateInfoBarBase::ViewHierarchyChanged(details
);
86 std::vector
<base::string16
> strings
;
87 TranslateInfoBarDelegate::GetAfterTranslateStrings(
88 &strings
, &swapped_language_buttons_
, autodetermined_source_language_
);
89 DCHECK_EQ(autodetermined_source_language_
? 2U : 3U, strings
.size());
91 label_1_
= CreateLabel(strings
[0]);
92 AddChildView(label_1_
);
94 TranslateInfoBarDelegate
* delegate
= GetDelegate();
95 original_language_menu_button_
= CreateMenuButton(base::string16(), this);
96 original_language_menu_model_
.reset(new TranslateLanguageMenuModel(
97 TranslateLanguageMenuModel::ORIGINAL
, delegate
, this,
98 original_language_menu_button_
, true));
99 target_language_menu_button_
= CreateMenuButton(base::string16(), this);
100 target_language_menu_model_
.reset(new TranslateLanguageMenuModel(
101 TranslateLanguageMenuModel::TARGET
, delegate
, this,
102 target_language_menu_button_
, true));
104 views::MenuButton
* first_button
, * second_button
;
105 GetButtons(&first_button
, &second_button
);
106 AddChildView(first_button
);
108 label_2_
= CreateLabel(strings
[1]);
109 AddChildView(label_2_
);
111 // These views may not always be shown, but adding them unconditionally
112 // prevents leaks and reduces NULL-checking elsewhere.
113 AddChildView(second_button
);
114 if (autodetermined_source_language_
)
115 second_button
->SetVisible(false);
116 label_3_
= CreateLabel(autodetermined_source_language_
?
117 base::string16() : strings
[2]);
118 AddChildView(label_3_
);
120 revert_button_
= CreateLabelButton(
121 this, l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_REVERT
));
122 AddChildView(revert_button_
);
124 options_menu_button_
= CreateMenuButton(
125 l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_OPTIONS
), this);
126 options_menu_model_
.reset(new OptionsMenuModel(delegate
));
127 AddChildView(options_menu_button_
);
129 // This must happen after adding all other children so InfoBarView can ensure
130 // the close button is the last child.
131 TranslateInfoBarBase::ViewHierarchyChanged(details
);
133 // These must happen after adding all children because they trigger layout,
134 // which assumes that particular children (e.g. the close button) have already
136 UpdateLanguageButtonText(original_language_menu_button_
,
137 delegate
->language_name_at(delegate
->original_language_index()));
138 UpdateLanguageButtonText(target_language_menu_button_
,
139 delegate
->language_name_at(delegate
->target_language_index()));
142 void AfterTranslateInfoBar::ButtonPressed(views::Button
* sender
,
143 const ui::Event
& event
) {
145 return; // We're closing; don't call anything, it might access the owner.
146 if (sender
== revert_button_
)
147 GetDelegate()->RevertTranslation();
149 TranslateInfoBarBase::ButtonPressed(sender
, event
);
152 int AfterTranslateInfoBar::ContentMinimumWidth() const {
153 return label_1_
->GetMinimumSize().width() +
154 label_2_
->GetMinimumSize().width() + label_3_
->GetMinimumSize().width() +
158 void AfterTranslateInfoBar::OnMenuButtonClicked(views::View
* source
,
159 const gfx::Point
& point
) {
161 return; // We're closing; don't call anything, it might access the owner.
162 if (source
== original_language_menu_button_
) {
163 RunMenuAt(original_language_menu_model_
.get(),
164 original_language_menu_button_
,
165 views::MENU_ANCHOR_TOPLEFT
);
166 } else if (source
== target_language_menu_button_
) {
167 RunMenuAt(target_language_menu_model_
.get(),
168 target_language_menu_button_
,
169 views::MENU_ANCHOR_TOPLEFT
);
171 DCHECK_EQ(options_menu_button_
, source
);
172 RunMenuAt(options_menu_model_
.get(),
173 options_menu_button_
,
174 views::MENU_ANCHOR_TOPRIGHT
);
178 void AfterTranslateInfoBar::GetButtons(
179 views::MenuButton
** first_button
,
180 views::MenuButton
** second_button
) const {
181 *first_button
= original_language_menu_button_
;
182 *second_button
= target_language_menu_button_
;
183 if (swapped_language_buttons_
|| autodetermined_source_language_
)
184 std::swap(*first_button
, *second_button
);
187 int AfterTranslateInfoBar::NonLabelWidth() const {
188 views::MenuButton
* first_button
, *second_button
;
189 GetButtons(&first_button
, &second_button
);
190 int width
= (label_1_
->text().empty() ? 0 : kButtonInLabelSpacing
) +
191 first_button
->width() +
192 (label_2_
->text().empty() ? 0 : kButtonInLabelSpacing
);
193 if (!autodetermined_source_language_
) {
195 (label_2_
->text().empty() ?
196 kButtonButtonSpacing
: kButtonInLabelSpacing
) +
197 second_button
->width() +
198 (label_3_
->text().empty() ? 0 : kButtonInLabelSpacing
);
200 return width
+ kEndOfLabelSpacing
+ revert_button_
->width() +
201 kEndOfLabelSpacing
+ options_menu_button_
->width();