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