// 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()); }