Home | History | Annotate | Download | only in infobars
      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/translate_infobar_base.h"
      6 
      7 #include "base/utf_string_conversions.h"
      8 #include "chrome/browser/translate/translate_infobar_delegate.h"
      9 #include "chrome/browser/ui/views/infobars/after_translate_infobar.h"
     10 #include "chrome/browser/ui/views/infobars/before_translate_infobar.h"
     11 #include "chrome/browser/ui/views/infobars/infobar_button_border.h"
     12 #include "chrome/browser/ui/views/infobars/translate_message_infobar.h"
     13 #include "grit/theme_resources.h"
     14 #include "ui/base/animation/slide_animation.h"
     15 #include "ui/base/resource/resource_bundle.h"
     16 #include "ui/gfx/canvas_skia.h"
     17 #include "views/controls/button/menu_button.h"
     18 #include "views/controls/label.h"
     19 
     20 // TranslateInfoBarDelegate ---------------------------------------------------
     21 
     22 InfoBar* TranslateInfoBarDelegate::CreateInfoBar() {
     23   TranslateInfoBarBase* infobar = NULL;
     24   switch (type_) {
     25     case BEFORE_TRANSLATE:
     26       infobar = new BeforeTranslateInfoBar(this);
     27       break;
     28     case AFTER_TRANSLATE:
     29       infobar = new AfterTranslateInfoBar(this);
     30       break;
     31     case TRANSLATING:
     32     case TRANSLATION_ERROR:
     33       infobar = new TranslateMessageInfoBar(this);
     34       break;
     35     default:
     36       NOTREACHED();
     37   }
     38   infobar_view_ = infobar;
     39   return infobar;
     40 }
     41 
     42 // TranslateInfoBarBase -------------------------------------------------------
     43 
     44 // static
     45 const int TranslateInfoBarBase::kButtonInLabelSpacing = 5;
     46 
     47 TranslateInfoBarBase::TranslateInfoBarBase(TranslateInfoBarDelegate* delegate)
     48     : InfoBarView(delegate),
     49       error_background_(InfoBarDelegate::WARNING_TYPE) {
     50 }
     51 
     52 TranslateInfoBarBase::~TranslateInfoBarBase() {
     53 }
     54 
     55 void TranslateInfoBarBase::ViewHierarchyChanged(bool is_add,
     56                                                 View* parent,
     57                                                 View* child) {
     58   if (is_add && (child == this) && (background_color_animation_ == NULL)) {
     59     background_color_animation_.reset(new ui::SlideAnimation(this));
     60     background_color_animation_->SetTweenType(ui::Tween::LINEAR);
     61     background_color_animation_->SetSlideDuration(500);
     62     TranslateInfoBarDelegate::BackgroundAnimationType animation =
     63         GetDelegate()->background_animation_type();
     64     if (animation == TranslateInfoBarDelegate::NORMAL_TO_ERROR) {
     65       background_color_animation_->Show();
     66     } else if (animation == TranslateInfoBarDelegate::ERROR_TO_NORMAL) {
     67       // Hide() runs the animation in reverse.
     68       background_color_animation_->Reset(1.0);
     69       background_color_animation_->Hide();
     70     }
     71   }
     72 
     73   // This must happen after adding all other children so InfoBarView can ensure
     74   // the close button is the last child.
     75   InfoBarView::ViewHierarchyChanged(is_add, parent, child);
     76 }
     77 
     78 void TranslateInfoBarBase::UpdateLanguageButtonText(
     79     views::MenuButton* button,
     80     LanguagesMenuModel::LanguageType language_type) {
     81   TranslateInfoBarDelegate* delegate = GetDelegate();
     82   button->SetText(UTF16ToWideHack(delegate->GetLanguageDisplayableNameAt(
     83       (language_type == LanguagesMenuModel::ORIGINAL) ?
     84           delegate->original_language_index() :
     85           delegate->target_language_index())));
     86   // The button may have to grow to show the new text.
     87   Layout();
     88   SchedulePaint();
     89 }
     90 
     91 TranslateInfoBarDelegate* TranslateInfoBarBase::GetDelegate() {
     92   return delegate()->AsTranslateInfoBarDelegate();
     93 }
     94 
     95 void TranslateInfoBarBase::OnPaintBackground(gfx::Canvas* canvas) {
     96   // We need to set the separator color for |error_background_| like
     97   // InfoBarView::Layout() does for the normal background.
     98   const InfoBarContainer::Delegate* delegate = container_delegate();
     99   if (delegate)
    100     error_background_.set_separator_color(delegate->GetInfoBarSeparatorColor());
    101 
    102   // If we're not animating, simply paint the background for the current state.
    103   if (!background_color_animation_->is_animating()) {
    104     GetBackground().Paint(canvas, this);
    105     return;
    106   }
    107 
    108   FadeBackground(canvas, 1.0 - background_color_animation_->GetCurrentValue(),
    109                  *background());
    110   FadeBackground(canvas, background_color_animation_->GetCurrentValue(),
    111                  error_background_);
    112 }
    113 
    114 void TranslateInfoBarBase::AnimationProgressed(const ui::Animation* animation) {
    115   if (animation == background_color_animation_.get())
    116     SchedulePaint();  // That'll trigger a PaintBackgroud.
    117   else
    118     InfoBarView::AnimationProgressed(animation);
    119 }
    120 
    121 const views::Background& TranslateInfoBarBase::GetBackground() {
    122   return GetDelegate()->IsError() ? error_background_ : *background();
    123 }
    124 
    125 void TranslateInfoBarBase::FadeBackground(gfx::Canvas* canvas,
    126                                           double animation_value,
    127                                           const views::Background& background) {
    128   // Draw the background into an offscreen buffer with alpha value per animation
    129   // value, then blend it back into the current canvas.
    130   canvas->SaveLayerAlpha(static_cast<int>(animation_value * 255));
    131   canvas->AsCanvasSkia()->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode);
    132   background.Paint(canvas, this);
    133   canvas->Restore();
    134 }
    135