1 // Copyright (c) 2011 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.
4
5 #include "chrome/browser/ui/views/infobars/after_translate_infobar.h"
6
7 #include "base/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 "views/controls/button/menu_button.h"
12 #include "views/controls/label.h"
13 #include "views/controls/menu/menu_2.h"
14
AfterTranslateInfoBar(TranslateInfoBarDelegate * delegate)15 AfterTranslateInfoBar::AfterTranslateInfoBar(
16 TranslateInfoBarDelegate* delegate)
17 : TranslateInfoBarBase(delegate),
18 label_1_(NULL),
19 label_2_(NULL),
20 label_3_(NULL),
21 original_language_menu_button_(NULL),
22 target_language_menu_button_(NULL),
23 revert_button_(NULL),
24 options_menu_button_(NULL),
25 original_language_menu_model_(delegate, LanguagesMenuModel::ORIGINAL),
26 original_language_menu_(new views::Menu2(&original_language_menu_model_)),
27 target_language_menu_model_(delegate, LanguagesMenuModel::TARGET),
28 target_language_menu_(new views::Menu2(&target_language_menu_model_)),
29 options_menu_model_(delegate),
30 options_menu_(new views::Menu2(&options_menu_model_)),
31 swapped_language_buttons_(false) {
32 }
33
~AfterTranslateInfoBar()34 AfterTranslateInfoBar::~AfterTranslateInfoBar() {
35 }
36
Layout()37 void AfterTranslateInfoBar::Layout() {
38 TranslateInfoBarBase::Layout();
39
40 int available_width = std::max(0, EndX() - StartX() - ContentMinimumWidth());
41 gfx::Size label_1_size = label_1_->GetPreferredSize();
42 label_1_->SetBounds(StartX(), OffsetY(label_1_size),
43 std::min(label_1_size.width(), available_width), label_1_size.height());
44 available_width = std::max(0, available_width - label_1_size.width());
45
46 views::MenuButton* first_button = original_language_menu_button_;
47 views::MenuButton* second_button = target_language_menu_button_;
48 if (swapped_language_buttons_)
49 std::swap(first_button, second_button);
50 gfx::Size first_button_size = first_button->GetPreferredSize();
51 first_button->SetBounds(label_1_->bounds().right() + kButtonInLabelSpacing,
52 OffsetY(first_button_size), first_button_size.width(),
53 first_button_size.height());
54
55 gfx::Size label_2_size = label_2_->GetPreferredSize();
56 label_2_->SetBounds(first_button->bounds().right() + kButtonInLabelSpacing,
57 OffsetY(label_2_size), std::min(label_2_size.width(), available_width),
58 label_2_size.height());
59 available_width = std::max(0, available_width - label_2_size.width());
60
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());
65
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());
70
71 gfx::Size revert_button_size = revert_button_->GetPreferredSize();
72 revert_button_->SetBounds(label_3_->bounds().right() + kButtonInLabelSpacing,
73 OffsetY(revert_button_size), revert_button_size.width(),
74 revert_button_size.height());
75
76 gfx::Size options_size = options_menu_button_->GetPreferredSize();
77 options_menu_button_->SetBounds(EndX() - options_size.width(),
78 OffsetY(options_size), options_size.width(), options_size.height());
79 }
80
ViewHierarchyChanged(bool is_add,View * parent,View * child)81 void AfterTranslateInfoBar::ViewHierarchyChanged(bool is_add,
82 View* parent,
83 View* child) {
84 if (!is_add || (child != this) || (label_1_ != NULL)) {
85 TranslateInfoBarBase::ViewHierarchyChanged(is_add, parent, child);
86 return;
87 }
88
89 std::vector<string16> strings;
90 GetDelegate()->GetAfterTranslateStrings(&strings, &swapped_language_buttons_);
91 DCHECK_EQ(3U, strings.size());
92
93 label_1_ = CreateLabel(strings[0]);
94 AddChildView(label_1_);
95
96 original_language_menu_button_ = CreateMenuButton(string16(), true, this);
97 target_language_menu_button_ = CreateMenuButton(string16(), true, this);
98 AddChildView(swapped_language_buttons_ ?
99 target_language_menu_button_ : original_language_menu_button_);
100
101 label_2_ = CreateLabel(strings[1]);
102 AddChildView(label_2_);
103
104 AddChildView(swapped_language_buttons_ ?
105 original_language_menu_button_ : target_language_menu_button_);
106
107 label_3_ = CreateLabel(strings[2]);
108 AddChildView(label_3_);
109
110 revert_button_ = CreateTextButton(this,
111 l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_REVERT), false);
112 AddChildView(revert_button_);
113
114 options_menu_button_ = CreateMenuButton(
115 l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_OPTIONS), false, this);
116 AddChildView(options_menu_button_);
117
118 // This must happen after adding all other children so InfoBarView can ensure
119 // the close button is the last child.
120 TranslateInfoBarBase::ViewHierarchyChanged(is_add, parent, child);
121
122 // These must happen after adding all children because they trigger layout,
123 // which assumes that particular children (e.g. the close button) have already
124 // been added.
125 OriginalLanguageChanged();
126 TargetLanguageChanged();
127 }
128
ButtonPressed(views::Button * sender,const views::Event & event)129 void AfterTranslateInfoBar::ButtonPressed(views::Button* sender,
130 const views::Event& event) {
131 if (sender == revert_button_)
132 GetDelegate()->RevertTranslation();
133 else
134 TranslateInfoBarBase::ButtonPressed(sender, event);
135 }
136
ContentMinimumWidth() const137 int AfterTranslateInfoBar::ContentMinimumWidth() const {
138 return
139 (kButtonInLabelSpacing +
140 original_language_menu_button_->GetPreferredSize().width() +
141 kButtonInLabelSpacing) +
142 (kButtonInLabelSpacing +
143 target_language_menu_button_->GetPreferredSize().width() +
144 kButtonInLabelSpacing) +
145 (kButtonInLabelSpacing + revert_button_->GetPreferredSize().width()) +
146 (kEndOfLabelSpacing + options_menu_button_->GetPreferredSize().width());
147 }
148
OriginalLanguageChanged()149 void AfterTranslateInfoBar::OriginalLanguageChanged() {
150 UpdateLanguageButtonText(original_language_menu_button_,
151 LanguagesMenuModel::ORIGINAL);
152 }
153
TargetLanguageChanged()154 void AfterTranslateInfoBar::TargetLanguageChanged() {
155 UpdateLanguageButtonText(target_language_menu_button_,
156 LanguagesMenuModel::TARGET);
157 }
158
RunMenu(View * source,const gfx::Point & pt)159 void AfterTranslateInfoBar::RunMenu(View* source, const gfx::Point& pt) {
160 if (source == original_language_menu_button_) {
161 original_language_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT);
162 } else if (source == target_language_menu_button_) {
163 target_language_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT);
164 } else {
165 DCHECK_EQ(options_menu_button_, source);
166 options_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT);
167 }
168 }
169