| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ui/gtk/infobars/translate_infobar_base_gtk.h" |
| |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/browser/translate/options_menu_model.h" |
| #include "chrome/browser/translate/translate_infobar_delegate.h" |
| #include "chrome/browser/ui/gtk/gtk_util.h" |
| #include "chrome/browser/ui/gtk/infobars/after_translate_infobar_gtk.h" |
| #include "chrome/browser/ui/gtk/infobars/before_translate_infobar_gtk.h" |
| #include "chrome/browser/ui/gtk/infobars/translate_message_infobar_gtk.h" |
| #include "chrome/browser/ui/gtk/menu_gtk.h" |
| #include "grit/generated_resources.h" |
| #include "ui/base/gtk/gtk_signal_registrar.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/gfx/animation/slide_animation.h" |
| #include "ui/gfx/canvas.h" |
| |
| |
| // TranslateInfoBarDelegate --------------------------------------------------- |
| |
| InfoBar* TranslateInfoBarDelegate::CreateInfoBar(InfoBarService* owner) { |
| if (infobar_type_ == BEFORE_TRANSLATE) |
| return new BeforeTranslateInfoBar(owner, this); |
| if (infobar_type_ == AFTER_TRANSLATE) |
| return new AfterTranslateInfoBar(owner, this); |
| return new TranslateMessageInfoBar(owner, this); |
| } |
| |
| |
| // TranslateInfoBarBase ------------------------------------------------------- |
| |
| TranslateInfoBarBase::TranslateInfoBarBase(InfoBarService* owner, |
| TranslateInfoBarDelegate* delegate) |
| : InfoBarGtk(owner, delegate), |
| background_error_percent_(0) { |
| DCHECK(delegate); |
| TranslateInfoBarDelegate::BackgroundAnimationType animation = |
| delegate->background_animation_type(); |
| if (animation != TranslateInfoBarDelegate::NONE) { |
| background_color_animation_.reset(new gfx::SlideAnimation(this)); |
| background_color_animation_->SetTweenType(gfx::Tween::LINEAR); |
| background_color_animation_->SetSlideDuration(500); |
| if (animation == TranslateInfoBarDelegate::NORMAL_TO_ERROR) { |
| background_color_animation_->Show(); |
| } else { |
| DCHECK_EQ(TranslateInfoBarDelegate::ERROR_TO_NORMAL, animation); |
| // Hide() runs the animation in reverse. |
| background_color_animation_->Reset(1.0); |
| background_color_animation_->Hide(); |
| } |
| } else { |
| background_error_percent_ = delegate->is_error() ? 1 : 0; |
| } |
| } |
| |
| TranslateInfoBarBase::~TranslateInfoBarBase() { |
| } |
| |
| void TranslateInfoBarBase::AnimationProgressed( |
| const gfx::Animation* animation) { |
| DCHECK(widget()); |
| if (animation == background_color_animation_.get()) { |
| background_error_percent_ = animation->GetCurrentValue(); |
| // Queue the info bar widget for redisplay so it repaints its background. |
| gtk_widget_queue_draw(widget()); |
| } else { |
| InfoBar::AnimationProgressed(animation); |
| } |
| } |
| |
| void TranslateInfoBarBase::GetTopColor(InfoBarDelegate::Type type, |
| double* r, double* g, double* b) { |
| if (background_error_percent_ <= 0) { |
| InfoBarGtk::GetTopColor(InfoBarDelegate::PAGE_ACTION_TYPE, r, g, b); |
| } else if (background_error_percent_ >= 1) { |
| InfoBarGtk::GetTopColor(InfoBarDelegate::WARNING_TYPE, r, g, b); |
| } else { |
| double normal_r, normal_g, normal_b; |
| InfoBarGtk::GetTopColor(InfoBarDelegate::PAGE_ACTION_TYPE, |
| &normal_r, &normal_g, &normal_b); |
| |
| double error_r, error_g, error_b; |
| InfoBarGtk::GetTopColor(InfoBarDelegate::WARNING_TYPE, |
| &error_r, &error_g, &error_b); |
| |
| double offset_r = error_r - normal_r; |
| double offset_g = error_g - normal_g; |
| double offset_b = error_b - normal_b; |
| |
| *r = normal_r + (background_error_percent_ * offset_r); |
| *g = normal_g + (background_error_percent_ * offset_g); |
| *b = normal_b + (background_error_percent_ * offset_b); |
| } |
| } |
| |
| void TranslateInfoBarBase::GetBottomColor(InfoBarDelegate::Type type, |
| double* r, double* g, double* b) { |
| if (background_error_percent_ <= 0) { |
| InfoBarGtk::GetBottomColor(InfoBarDelegate::PAGE_ACTION_TYPE, r, g, b); |
| } else if (background_error_percent_ >= 1) { |
| InfoBarGtk::GetBottomColor(InfoBarDelegate::WARNING_TYPE, r, g, b); |
| } else { |
| double normal_r, normal_g, normal_b; |
| InfoBarGtk::GetBottomColor(InfoBarDelegate::PAGE_ACTION_TYPE, |
| &normal_r, &normal_g, &normal_b); |
| |
| double error_r, error_g, error_b; |
| InfoBarGtk::GetBottomColor(InfoBarDelegate::WARNING_TYPE, |
| &error_r, &error_g, &error_b); |
| |
| double offset_r = error_r - normal_r; |
| double offset_g = error_g - normal_g; |
| double offset_b = error_b - normal_b; |
| |
| *r = normal_r + (background_error_percent_ * offset_r); |
| *g = normal_g + (background_error_percent_ * offset_g); |
| *b = normal_b + (background_error_percent_ * offset_b); |
| } |
| } |
| |
| void TranslateInfoBarBase::InitWidgets() { |
| InfoBarGtk::InitWidgets(); |
| |
| if (!ShowOptionsMenuButton()) |
| return; |
| |
| // The options button sits outside the translate_box so that it can be end |
| // packed in hbox(). |
| GtkWidget* options_menu_button = CreateMenuButton( |
| l10n_util::GetStringUTF8(IDS_TRANSLATE_INFOBAR_OPTIONS)); |
| signals()->Connect(options_menu_button, "clicked", |
| G_CALLBACK(&OnOptionsClickedThunk), this); |
| gtk_widget_show_all(options_menu_button); |
| gtk_util::CenterWidgetInHBox(hbox(), options_menu_button, true, 0); |
| } |
| |
| bool TranslateInfoBarBase::ShowOptionsMenuButton() const { |
| return false; |
| } |
| |
| GtkWidget* TranslateInfoBarBase::CreateLanguageCombobox( |
| size_t selected_language, |
| size_t exclude_language) { |
| DCHECK(selected_language != exclude_language); |
| |
| GtkListStore* model = gtk_list_store_new(LANGUAGE_COMBO_COLUMN_COUNT, |
| G_TYPE_INT, G_TYPE_STRING); |
| bool set_selection = false; |
| GtkTreeIter selected_iter; |
| TranslateInfoBarDelegate* delegate = GetDelegate(); |
| for (size_t i = 0; i < delegate->num_languages(); ++i) { |
| if (i == exclude_language) |
| continue; |
| GtkTreeIter tree_iter; |
| const string16& name = delegate->language_name_at(i); |
| |
| gtk_list_store_append(model, &tree_iter); |
| gtk_list_store_set(model, &tree_iter, |
| LANGUAGE_COMBO_COLUMN_ID, i, |
| LANGUAGE_COMBO_COLUMN_NAME, UTF16ToUTF8(name).c_str(), |
| -1); |
| if (i == selected_language) { |
| selected_iter = tree_iter; |
| set_selection = true; |
| } |
| } |
| |
| GtkWidget* combobox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model)); |
| if (set_selection) |
| gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combobox), &selected_iter); |
| g_object_unref(model); |
| GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); |
| gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), renderer, TRUE); |
| gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combobox), renderer, |
| "text", LANGUAGE_COMBO_COLUMN_NAME, |
| NULL); |
| return combobox; |
| } |
| |
| // static |
| size_t TranslateInfoBarBase::GetLanguageComboboxActiveId(GtkComboBox* combo) { |
| GtkTreeIter iter; |
| if (!gtk_combo_box_get_active_iter(combo, &iter)) |
| return 0; |
| |
| gint id = 0; |
| gtk_tree_model_get(gtk_combo_box_get_model(combo), &iter, |
| LANGUAGE_COMBO_COLUMN_ID, &id, |
| -1); |
| return static_cast<size_t>(id); |
| } |
| |
| TranslateInfoBarDelegate* TranslateInfoBarBase::GetDelegate() { |
| return static_cast<TranslateInfoBarDelegate*>(delegate()); |
| } |
| |
| void TranslateInfoBarBase::OnOptionsClicked(GtkWidget* sender) { |
| menu_model_.reset(new OptionsMenuModel(GetDelegate())); |
| ShowMenuWithModel(sender, NULL, menu_model_.get()); |
| } |