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/gtk/infobars/translate_infobar_base_gtk.h"
      6 
      7 #include "base/strings/utf_string_conversions.h"
      8 #include "chrome/browser/translate/options_menu_model.h"
      9 #include "chrome/browser/translate/translate_infobar_delegate.h"
     10 #include "chrome/browser/ui/gtk/gtk_util.h"
     11 #include "chrome/browser/ui/gtk/infobars/after_translate_infobar_gtk.h"
     12 #include "chrome/browser/ui/gtk/infobars/before_translate_infobar_gtk.h"
     13 #include "chrome/browser/ui/gtk/infobars/translate_message_infobar_gtk.h"
     14 #include "chrome/browser/ui/gtk/menu_gtk.h"
     15 #include "grit/generated_resources.h"
     16 #include "ui/base/gtk/gtk_signal_registrar.h"
     17 #include "ui/base/l10n/l10n_util.h"
     18 #include "ui/gfx/animation/slide_animation.h"
     19 #include "ui/gfx/canvas.h"
     20 
     21 
     22 // TranslateInfoBarDelegate ---------------------------------------------------
     23 
     24 // static
     25 scoped_ptr<InfoBar> TranslateInfoBarDelegate::CreateInfoBar(
     26     scoped_ptr<TranslateInfoBarDelegate> delegate) {
     27   if (delegate->infobar_type() == BEFORE_TRANSLATE)
     28     return scoped_ptr<InfoBar>(new BeforeTranslateInfoBar(delegate.Pass()));
     29   if (delegate->infobar_type() == AFTER_TRANSLATE)
     30     return scoped_ptr<InfoBar>(new AfterTranslateInfoBar(delegate.Pass()));
     31   return scoped_ptr<InfoBar>(new TranslateMessageInfoBar(delegate.Pass()));
     32 }
     33 
     34 
     35 // TranslateInfoBarBase -------------------------------------------------------
     36 
     37 TranslateInfoBarBase::TranslateInfoBarBase(
     38     scoped_ptr<TranslateInfoBarDelegate> delegate)
     39     : InfoBarGtk(delegate.PassAs<InfoBarDelegate>()),
     40       background_error_percent_(0) {
     41   TranslateInfoBarDelegate* translate_delegate = GetDelegate();
     42   DCHECK(translate_delegate);
     43   TranslateInfoBarDelegate::BackgroundAnimationType animation =
     44       translate_delegate->background_animation_type();
     45   if (animation != TranslateInfoBarDelegate::NONE) {
     46     background_color_animation_.reset(new gfx::SlideAnimation(this));
     47     background_color_animation_->SetTweenType(gfx::Tween::LINEAR);
     48     background_color_animation_->SetSlideDuration(500);
     49     if (animation == TranslateInfoBarDelegate::NORMAL_TO_ERROR) {
     50       background_color_animation_->Show();
     51     } else {
     52       DCHECK_EQ(TranslateInfoBarDelegate::ERROR_TO_NORMAL, animation);
     53       // Hide() runs the animation in reverse.
     54       background_color_animation_->Reset(1.0);
     55       background_color_animation_->Hide();
     56     }
     57   } else {
     58     background_error_percent_ = translate_delegate->is_error() ? 1 : 0;
     59   }
     60 }
     61 
     62 TranslateInfoBarBase::~TranslateInfoBarBase() {
     63 }
     64 
     65 void TranslateInfoBarBase::AnimationProgressed(
     66     const gfx::Animation* animation) {
     67   DCHECK(widget());
     68   if (animation == background_color_animation_.get()) {
     69     background_error_percent_ = animation->GetCurrentValue();
     70     // Queue the info bar widget for redisplay so it repaints its background.
     71     gtk_widget_queue_draw(widget());
     72   } else {
     73     InfoBar::AnimationProgressed(animation);
     74   }
     75 }
     76 
     77 void TranslateInfoBarBase::PlatformSpecificSetOwner() {
     78   InfoBarGtk::PlatformSpecificSetOwner();
     79 
     80   if (!ShowOptionsMenuButton())
     81     return;
     82 
     83   // The options button sits outside the translate_box so that it can be end
     84   // packed in hbox().
     85   GtkWidget* options_menu_button = CreateMenuButton(
     86       l10n_util::GetStringUTF8(IDS_TRANSLATE_INFOBAR_OPTIONS));
     87   signals()->Connect(options_menu_button, "clicked",
     88                      G_CALLBACK(&OnOptionsClickedThunk), this);
     89   gtk_widget_show_all(options_menu_button);
     90   gtk_util::CenterWidgetInHBox(hbox(), options_menu_button, true, 0);
     91 }
     92 
     93 void TranslateInfoBarBase::GetTopColor(InfoBarDelegate::Type type,
     94                                        double* r, double* g, double* b) {
     95   if (background_error_percent_ <= 0) {
     96     InfoBarGtk::GetTopColor(InfoBarDelegate::PAGE_ACTION_TYPE, r, g, b);
     97   } else if (background_error_percent_ >= 1) {
     98     InfoBarGtk::GetTopColor(InfoBarDelegate::WARNING_TYPE, r, g, b);
     99   } else {
    100     double normal_r, normal_g, normal_b;
    101     InfoBarGtk::GetTopColor(InfoBarDelegate::PAGE_ACTION_TYPE,
    102                             &normal_r, &normal_g, &normal_b);
    103 
    104     double error_r, error_g, error_b;
    105     InfoBarGtk::GetTopColor(InfoBarDelegate::WARNING_TYPE,
    106                             &error_r, &error_g, &error_b);
    107 
    108     double offset_r = error_r - normal_r;
    109     double offset_g = error_g - normal_g;
    110     double offset_b = error_b - normal_b;
    111 
    112     *r = normal_r + (background_error_percent_ * offset_r);
    113     *g = normal_g + (background_error_percent_ * offset_g);
    114     *b = normal_b + (background_error_percent_ * offset_b);
    115   }
    116 }
    117 
    118 void TranslateInfoBarBase::GetBottomColor(InfoBarDelegate::Type type,
    119                                           double* r, double* g, double* b) {
    120   if (background_error_percent_ <= 0) {
    121     InfoBarGtk::GetBottomColor(InfoBarDelegate::PAGE_ACTION_TYPE, r, g, b);
    122   } else if (background_error_percent_ >= 1) {
    123     InfoBarGtk::GetBottomColor(InfoBarDelegate::WARNING_TYPE, r, g, b);
    124   } else {
    125     double normal_r, normal_g, normal_b;
    126     InfoBarGtk::GetBottomColor(InfoBarDelegate::PAGE_ACTION_TYPE,
    127                                &normal_r, &normal_g, &normal_b);
    128 
    129     double error_r, error_g, error_b;
    130     InfoBarGtk::GetBottomColor(InfoBarDelegate::WARNING_TYPE,
    131                                &error_r, &error_g, &error_b);
    132 
    133     double offset_r = error_r - normal_r;
    134     double offset_g = error_g - normal_g;
    135     double offset_b = error_b - normal_b;
    136 
    137     *r = normal_r + (background_error_percent_ * offset_r);
    138     *g = normal_g + (background_error_percent_ * offset_g);
    139     *b = normal_b + (background_error_percent_ * offset_b);
    140   }
    141 }
    142 
    143 bool TranslateInfoBarBase::ShowOptionsMenuButton() const {
    144   return false;
    145 }
    146 
    147 GtkWidget* TranslateInfoBarBase::CreateLanguageCombobox(
    148     size_t selected_language,
    149     size_t exclude_language) {
    150   DCHECK(selected_language != exclude_language);
    151 
    152   GtkListStore* model = gtk_list_store_new(LANGUAGE_COMBO_COLUMN_COUNT,
    153                                            G_TYPE_INT, G_TYPE_STRING);
    154   bool set_selection = false;
    155   GtkTreeIter selected_iter;
    156   TranslateInfoBarDelegate* delegate = GetDelegate();
    157   for (size_t i = 0; i < delegate->num_languages(); ++i) {
    158     if (i == exclude_language)
    159       continue;
    160     GtkTreeIter tree_iter;
    161     const base::string16& name = delegate->language_name_at(i);
    162 
    163     gtk_list_store_append(model, &tree_iter);
    164     gtk_list_store_set(model, &tree_iter,
    165                        LANGUAGE_COMBO_COLUMN_ID, i,
    166                        LANGUAGE_COMBO_COLUMN_NAME, UTF16ToUTF8(name).c_str(),
    167                        -1);
    168     if (i == selected_language) {
    169       selected_iter = tree_iter;
    170       set_selection = true;
    171     }
    172   }
    173 
    174   GtkWidget* combobox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model));
    175   if (set_selection)
    176     gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combobox), &selected_iter);
    177   g_object_unref(model);
    178   GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
    179   gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), renderer, TRUE);
    180   gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combobox), renderer,
    181                                  "text", LANGUAGE_COMBO_COLUMN_NAME,
    182                                  NULL);
    183   return combobox;
    184 }
    185 
    186 // static
    187 size_t TranslateInfoBarBase::GetLanguageComboboxActiveId(GtkComboBox* combo) {
    188   GtkTreeIter iter;
    189   if (!gtk_combo_box_get_active_iter(combo, &iter))
    190     return 0;
    191 
    192   gint id = 0;
    193   gtk_tree_model_get(gtk_combo_box_get_model(combo), &iter,
    194                      LANGUAGE_COMBO_COLUMN_ID, &id,
    195                      -1);
    196   return static_cast<size_t>(id);
    197 }
    198 
    199 TranslateInfoBarDelegate* TranslateInfoBarBase::GetDelegate() {
    200   return static_cast<TranslateInfoBarDelegate*>(delegate());
    201 }
    202 
    203 void TranslateInfoBarBase::OnOptionsClicked(GtkWidget* sender) {
    204   menu_model_.reset(new OptionsMenuModel(GetDelegate()));
    205   ShowMenuWithModel(sender, NULL, menu_model_.get());
    206 }
    207