- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / gtk / infobars / translate_infobar_base_gtk.cc
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 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 gfx::SlideAnimation(this));
44     background_color_animation_->SetTweenType(gfx::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(
63     const gfx::Animation* animation) {
64   DCHECK(widget());
65   if (animation == background_color_animation_.get()) {
66     background_error_percent_ = animation->GetCurrentValue();
67     // Queue the info bar widget for redisplay so it repaints its background.
68     gtk_widget_queue_draw(widget());
69   } else {
70     InfoBar::AnimationProgressed(animation);
71   }
72 }
73
74 void TranslateInfoBarBase::GetTopColor(InfoBarDelegate::Type type,
75                                        double* r, double* g, double* b) {
76   if (background_error_percent_ <= 0) {
77     InfoBarGtk::GetTopColor(InfoBarDelegate::PAGE_ACTION_TYPE, r, g, b);
78   } else if (background_error_percent_ >= 1) {
79     InfoBarGtk::GetTopColor(InfoBarDelegate::WARNING_TYPE, r, g, b);
80   } else {
81     double normal_r, normal_g, normal_b;
82     InfoBarGtk::GetTopColor(InfoBarDelegate::PAGE_ACTION_TYPE,
83                             &normal_r, &normal_g, &normal_b);
84
85     double error_r, error_g, error_b;
86     InfoBarGtk::GetTopColor(InfoBarDelegate::WARNING_TYPE,
87                             &error_r, &error_g, &error_b);
88
89     double offset_r = error_r - normal_r;
90     double offset_g = error_g - normal_g;
91     double offset_b = error_b - normal_b;
92
93     *r = normal_r + (background_error_percent_ * offset_r);
94     *g = normal_g + (background_error_percent_ * offset_g);
95     *b = normal_b + (background_error_percent_ * offset_b);
96   }
97 }
98
99 void TranslateInfoBarBase::GetBottomColor(InfoBarDelegate::Type type,
100                                           double* r, double* g, double* b) {
101   if (background_error_percent_ <= 0) {
102     InfoBarGtk::GetBottomColor(InfoBarDelegate::PAGE_ACTION_TYPE, r, g, b);
103   } else if (background_error_percent_ >= 1) {
104     InfoBarGtk::GetBottomColor(InfoBarDelegate::WARNING_TYPE, r, g, b);
105   } else {
106     double normal_r, normal_g, normal_b;
107     InfoBarGtk::GetBottomColor(InfoBarDelegate::PAGE_ACTION_TYPE,
108                                &normal_r, &normal_g, &normal_b);
109
110     double error_r, error_g, error_b;
111     InfoBarGtk::GetBottomColor(InfoBarDelegate::WARNING_TYPE,
112                                &error_r, &error_g, &error_b);
113
114     double offset_r = error_r - normal_r;
115     double offset_g = error_g - normal_g;
116     double offset_b = error_b - normal_b;
117
118     *r = normal_r + (background_error_percent_ * offset_r);
119     *g = normal_g + (background_error_percent_ * offset_g);
120     *b = normal_b + (background_error_percent_ * offset_b);
121   }
122 }
123
124 void TranslateInfoBarBase::InitWidgets() {
125   InfoBarGtk::InitWidgets();
126
127   if (!ShowOptionsMenuButton())
128     return;
129
130   // The options button sits outside the translate_box so that it can be end
131   // packed in hbox().
132   GtkWidget* options_menu_button = CreateMenuButton(
133       l10n_util::GetStringUTF8(IDS_TRANSLATE_INFOBAR_OPTIONS));
134   signals()->Connect(options_menu_button, "clicked",
135                      G_CALLBACK(&OnOptionsClickedThunk), this);
136   gtk_widget_show_all(options_menu_button);
137   gtk_util::CenterWidgetInHBox(hbox(), options_menu_button, true, 0);
138 }
139
140 bool TranslateInfoBarBase::ShowOptionsMenuButton() const {
141   return false;
142 }
143
144 GtkWidget* TranslateInfoBarBase::CreateLanguageCombobox(
145     size_t selected_language,
146     size_t exclude_language) {
147   DCHECK(selected_language != exclude_language);
148
149   GtkListStore* model = gtk_list_store_new(LANGUAGE_COMBO_COLUMN_COUNT,
150                                            G_TYPE_INT, G_TYPE_STRING);
151   bool set_selection = false;
152   GtkTreeIter selected_iter;
153   TranslateInfoBarDelegate* delegate = GetDelegate();
154   for (size_t i = 0; i < delegate->num_languages(); ++i) {
155     if (i == exclude_language)
156       continue;
157     GtkTreeIter tree_iter;
158     const string16& name = delegate->language_name_at(i);
159
160     gtk_list_store_append(model, &tree_iter);
161     gtk_list_store_set(model, &tree_iter,
162                        LANGUAGE_COMBO_COLUMN_ID, i,
163                        LANGUAGE_COMBO_COLUMN_NAME, UTF16ToUTF8(name).c_str(),
164                        -1);
165     if (i == selected_language) {
166       selected_iter = tree_iter;
167       set_selection = true;
168     }
169   }
170
171   GtkWidget* combobox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model));
172   if (set_selection)
173     gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combobox), &selected_iter);
174   g_object_unref(model);
175   GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
176   gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), renderer, TRUE);
177   gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combobox), renderer,
178                                  "text", LANGUAGE_COMBO_COLUMN_NAME,
179                                  NULL);
180   return combobox;
181 }
182
183 // static
184 size_t TranslateInfoBarBase::GetLanguageComboboxActiveId(GtkComboBox* combo) {
185   GtkTreeIter iter;
186   if (!gtk_combo_box_get_active_iter(combo, &iter))
187     return 0;
188
189   gint id = 0;
190   gtk_tree_model_get(gtk_combo_box_get_model(combo), &iter,
191                      LANGUAGE_COMBO_COLUMN_ID, &id,
192                      -1);
193   return static_cast<size_t>(id);
194 }
195
196 TranslateInfoBarDelegate* TranslateInfoBarBase::GetDelegate() {
197   return static_cast<TranslateInfoBarDelegate*>(delegate());
198 }
199
200 void TranslateInfoBarBase::OnOptionsClicked(GtkWidget* sender) {
201   menu_model_.reset(new OptionsMenuModel(GetDelegate()));
202   ShowMenuWithModel(sender, NULL, menu_model_.get());
203 }