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