Home | History | Annotate | Download | only in infobars
      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.
      4 
      5 #include "chrome/browser/ui/views/infobars/after_translate_infobar.h"
      6 
      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"
     15 
     16 AfterTranslateInfoBar::AfterTranslateInfoBar(
     17     InfoBarService* owner,
     18     TranslateInfoBarDelegate* delegate)
     19     : TranslateInfoBarBase(owner, delegate),
     20       label_1_(NULL),
     21       label_2_(NULL),
     22       label_3_(NULL),
     23       original_language_menu_button_(NULL),
     24       target_language_menu_button_(NULL),
     25       revert_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;
     31 }
     32 
     33 AfterTranslateInfoBar::~AfterTranslateInfoBar() {
     34 }
     35 
     36 void AfterTranslateInfoBar::Layout() {
     37   TranslateInfoBarBase::Layout();
     38 
     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());
     44 
     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());
     53 
     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());
     59 
     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());
     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 
     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());
     79 
     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());
     83 }
     84 
     85 void AfterTranslateInfoBar::ViewHierarchyChanged(
     86     const ViewHierarchyChangedDetails& details) {
     87   if (!details.is_add || (details.child != this) || (label_1_ != NULL)) {
     88     TranslateInfoBarBase::ViewHierarchyChanged(details);
     89     return;
     90   }
     91 
     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());
     96 
     97   label_1_ = CreateLabel(strings[0]);
     98   AddChildView(label_1_);
     99 
    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_);
    111 
    112   label_2_ = CreateLabel(strings[1]);
    113   AddChildView(label_2_);
    114 
    115   if (!autodetermined_source_language_) {
    116     AddChildView(swapped_language_buttons_ ?
    117         original_language_menu_button_ : target_language_menu_button_);
    118 
    119     label_3_ = CreateLabel(strings[2]);
    120     AddChildView(label_3_);
    121   }
    122 
    123   revert_button_ = CreateLabelButton(this,
    124       l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_REVERT), false);
    125   AddChildView(revert_button_);
    126 
    127   options_menu_button_ = CreateMenuButton(
    128       l10n_util::GetStringUTF16(IDS_TRANSLATE_INFOBAR_OPTIONS), this);
    129   AddChildView(options_menu_button_);
    130 
    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);
    134 
    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
    137   // been added.
    138   if (!autodetermined_source_language_) {
    139     UpdateLanguageButtonText(original_language_menu_button_,
    140         delegate->language_name_at(delegate->original_language_index()));
    141   }
    142   UpdateLanguageButtonText(target_language_menu_button_,
    143       delegate->language_name_at(delegate->target_language_index()));
    144 }
    145 
    146 void AfterTranslateInfoBar::ButtonPressed(views::Button* sender,
    147                                           const ui::Event& event) {
    148   if (!owner())
    149     return;  // We're closing; don't call anything, it might access the owner.
    150   if (sender == revert_button_)
    151     GetDelegate()->RevertTranslation();
    152   else
    153     TranslateInfoBarBase::ButtonPressed(sender, event);
    154 }
    155 
    156 int AfterTranslateInfoBar::ContentMinimumWidth() const {
    157   return
    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());
    166 }
    167 
    168 void AfterTranslateInfoBar::OnMenuButtonClicked(views::View* source,
    169                                                 const gfx::Point& point) {
    170   if (!owner())
    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);
    178   } else {
    179     DCHECK_EQ(options_menu_button_, source);
    180     RunMenuAt(&options_menu_model_, options_menu_button_,
    181               views::MenuItemView::TOPRIGHT);
    182   }
    183 }
    184