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
15AfterTranslateInfoBar::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
34AfterTranslateInfoBar::~AfterTranslateInfoBar() {
35}
36
37void 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
81void 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
129void 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
137int 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
149void AfterTranslateInfoBar::OriginalLanguageChanged() {
150  UpdateLanguageButtonText(original_language_menu_button_,
151                           LanguagesMenuModel::ORIGINAL);
152}
153
154void AfterTranslateInfoBar::TargetLanguageChanged() {
155  UpdateLanguageButtonText(target_language_menu_button_,
156                           LanguagesMenuModel::TARGET);
157}
158
159void 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