| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/gtk/infobar_gtk.h" | 5 #include "chrome/browser/gtk/infobar_gtk.h" |
| 6 | 6 |
| 7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
| 8 | 8 |
| 9 #include "base/gfx/gtk_util.h" | 9 #include "base/gfx/gtk_util.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "chrome/browser/gtk/custom_button.h" | 11 #include "chrome/browser/gtk/custom_button.h" |
| 12 #include "chrome/browser/gtk/gtk_chrome_link_button.h" | 12 #include "chrome/browser/gtk/gtk_chrome_link_button.h" |
| 13 #include "chrome/browser/gtk/gtk_skinny_button.h" |
| 13 #include "chrome/browser/gtk/infobar_container_gtk.h" | 14 #include "chrome/browser/gtk/infobar_container_gtk.h" |
| 15 #include "chrome/browser/tab_contents/customize_geoloc_infobar_delegate.h" |
| 16 #include "chrome/browser/tab_contents/geoloc_infobar_delegate.h" |
| 14 #include "chrome/browser/tab_contents/infobar_delegate.h" | 17 #include "chrome/browser/tab_contents/infobar_delegate.h" |
| 15 #include "chrome/common/gtk_util.h" | 18 #include "chrome/common/gtk_util.h" |
| 16 | 19 |
| 17 namespace { | 20 namespace { |
| 18 | 21 |
| 19 const double kBackgroundColorTop[3] = | 22 const double kBackgroundColorTop[3] = |
| 20 {255.0 / 255.0, 242.0 / 255.0, 183.0 / 255.0}; | 23 {255.0 / 255.0, 242.0 / 255.0, 183.0 / 255.0}; |
| 21 const double kBackgroundColorBottom[3] = | 24 const double kBackgroundColorBottom[3] = |
| 22 {250.0 / 255.0, 230.0 / 255.0, 145.0 / 255.0}; | 25 {250.0 / 255.0, 230.0 / 255.0, 145.0 / 255.0}; |
| 23 | 26 |
| 24 // Border color (the top pixel of the infobar). | 27 // Border color (the top pixel of the infobar). |
| 25 const GdkColor kBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4); | 28 const GdkColor kBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4); |
| 26 | 29 |
| 27 // The total height of the info bar. | 30 // The total height of the info bar. |
| 28 const int kInfoBarHeight = 37; | 31 const int kInfoBarHeight = 37; |
| 29 | 32 |
| 30 // Pixels between infobar elements. | 33 // Pixels between infobar elements. |
| 31 const int kElementPadding = 5; | 34 const int kElementPadding = 5; |
| 32 | 35 |
| 33 // Extra padding on either end of info bar. | 36 // Extra padding on either end of info bar. |
| 34 const int kLeftPadding = 5; | 37 const int kLeftPadding = 5; |
| 35 const int kRightPadding = 5; | 38 const int kRightPadding = 5; |
| 36 | 39 |
| 37 static gboolean OnBackgroundExpose(GtkWidget* widget, GdkEventExpose* event, | 40 static gboolean OnBackgroundExpose(GtkWidget* widget, GdkEventExpose* event, |
| 38 gpointer unused) { | 41 InfoBarStyle *style) { |
| 42 CHECK(style); |
| 39 const int height = widget->allocation.height; | 43 const int height = widget->allocation.height; |
| 40 | 44 |
| 41 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); | 45 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); |
| 42 cairo_rectangle(cr, event->area.x, event->area.y, | 46 cairo_rectangle(cr, event->area.x, event->area.y, |
| 43 event->area.width, event->area.height); | 47 event->area.width, event->area.height); |
| 44 cairo_clip(cr); | 48 cairo_clip(cr); |
| 45 | 49 |
| 46 cairo_pattern_t* pattern = cairo_pattern_create_linear(0, 0, 0, height); | 50 cairo_pattern_t* pattern = cairo_pattern_create_linear(0, 0, 0, height); |
| 47 cairo_pattern_add_color_stop_rgb( | 51 cairo_pattern_add_color_stop_rgb( |
| 48 pattern, 0.0, | 52 pattern, 0.0, |
| 49 kBackgroundColorTop[0], kBackgroundColorTop[1], kBackgroundColorTop[2]); | 53 style->gradient_top_[0], style->gradient_top_[1], |
| 54 style->gradient_top_[2]); |
| 50 cairo_pattern_add_color_stop_rgb( | 55 cairo_pattern_add_color_stop_rgb( |
| 51 pattern, 1.0, | 56 pattern, 1.0, |
| 52 kBackgroundColorBottom[0], kBackgroundColorBottom[1], | 57 style->gradient_bottom_[0], style->gradient_bottom_[1], |
| 53 kBackgroundColorBottom[2]); | 58 style->gradient_bottom_[2]); |
| 59 |
| 54 cairo_set_source(cr, pattern); | 60 cairo_set_source(cr, pattern); |
| 55 cairo_paint(cr); | 61 cairo_paint(cr); |
| 56 cairo_pattern_destroy(pattern); | 62 cairo_pattern_destroy(pattern); |
| 57 | 63 |
| 58 cairo_destroy(cr); | 64 cairo_destroy(cr); |
| 59 | 65 |
| 60 return FALSE; | 66 return FALSE; |
| 61 } | 67 } |
| 62 | 68 |
| 63 } // namespace | 69 } // namespace |
| 70 InfoBarStyle::InfoBarStyle(const double top[3], |
| 71 const double bottom[3], |
| 72 int height, |
| 73 GdkColor text_color, |
| 74 bool even) |
| 75 : height_(height), |
| 76 text_color_(text_color), |
| 77 even_(even) { |
| 78 memcpy(gradient_top_, top, sizeof(gradient_top_)); |
| 79 memcpy(gradient_bottom_, bottom, sizeof(gradient_bottom_)); |
| 80 } |
| 81 InfoBarStyle::InfoBarStyle() : height_(0), even_(true) { |
| 82 memset(gradient_top_, 0, sizeof(gradient_top_)); |
| 83 memset(gradient_bottom_, 0, sizeof(gradient_bottom_)); |
| 84 } |
| 64 | 85 |
| 65 InfoBar::InfoBar(InfoBarDelegate* delegate) | 86 InfoBar::InfoBar(InfoBarDelegate* delegate) |
| 66 : container_(NULL), | 87 : container_(NULL), |
| 67 delegate_(delegate) { | 88 delegate_(delegate) { |
| 89 GtkWidget* outer_hbox = gtk_hbox_new(FALSE, kElementPadding); |
| 90 |
| 91 if (!delegate->GetStyle()) { |
| 92 InfoBarStyle def(kBackgroundColorTop, |
| 93 kBackgroundColorBottom, |
| 94 kInfoBarHeight, |
| 95 gfx::kGdkBlack, |
| 96 true); |
| 97 style_ = def; |
| 98 } else { |
| 99 style_ = *(delegate->GetStyle()); |
| 100 } |
| 101 |
| 102 vbox_ = gtk_vbox_new(style_.even_, 0); |
| 68 // Create |hbox_| and pad the sides. | 103 // Create |hbox_| and pad the sides. |
| 69 hbox_ = gtk_hbox_new(FALSE, kElementPadding); | 104 hbox_ = gtk_hbox_new(FALSE, kElementPadding); |
| 70 GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1); | 105 GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1); |
| 71 gtk_alignment_set_padding(GTK_ALIGNMENT(padding), | 106 gtk_alignment_set_padding(GTK_ALIGNMENT(padding), |
| 72 0, 0, kLeftPadding, kRightPadding); | 107 0, 0, kLeftPadding, kRightPadding); |
| 73 | 108 |
| 74 GtkWidget* bg_box = gtk_event_box_new(); | 109 GtkWidget* bg_box = gtk_event_box_new(); |
| 75 gtk_widget_set_app_paintable(bg_box, TRUE); | 110 gtk_widget_set_app_paintable(bg_box, TRUE); |
| 76 g_signal_connect(bg_box, "expose-event", | 111 g_signal_connect(bg_box, "expose-event", |
| 77 G_CALLBACK(OnBackgroundExpose), NULL); | 112 G_CALLBACK(OnBackgroundExpose), &style_); |
| 78 gtk_container_add(GTK_CONTAINER(padding), hbox_); | 113 gtk_container_add(GTK_CONTAINER(padding), outer_hbox); |
| 79 gtk_container_add(GTK_CONTAINER(bg_box), padding); | 114 gtk_container_add(GTK_CONTAINER(bg_box), padding); |
| 80 // The -1 on the kInfoBarHeight is to account for the border. | 115 // The -1 on the kInfoBarHeight is to account for the border. |
| 81 gtk_widget_set_size_request(bg_box, -1, kInfoBarHeight - 1); | 116 gtk_widget_set_size_request(bg_box, -1, style_.height_ - 1); |
| 82 | 117 |
| 83 border_bin_.Own(gtk_util::CreateGtkBorderBin(bg_box, &kBorderColor, | 118 border_bin_.Own(gtk_util::CreateGtkBorderBin(bg_box, &kBorderColor, |
| 84 0, 1, 0, 0)); | 119 0, 1, 0, 0)); |
| 85 | 120 |
| 86 // Add the icon on the left, if any. | 121 // Add the icon on the left, if any. |
| 87 SkBitmap* icon = delegate->GetIcon(); | 122 SkBitmap* icon = delegate->GetIcon(); |
| 88 if (icon) { | 123 if (icon) { |
| 89 GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(icon); | 124 GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(icon); |
| 90 GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf); | 125 GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf); |
| 91 g_object_unref(pixbuf); | 126 g_object_unref(pixbuf); |
| 92 gtk_box_pack_start(GTK_BOX(hbox_), image, FALSE, FALSE, 0); | 127 gtk_box_pack_start(GTK_BOX(outer_hbox), image, FALSE, FALSE, 0); |
| 93 } | 128 } |
| 94 | 129 |
| 130 gtk_box_pack_start(GTK_BOX(outer_hbox), vbox_, true, true, 0); |
| 131 gtk_box_pack_start(GTK_BOX(vbox_), hbox_, false, false, style_.even_ ? 0 : kEl
ementPadding); |
| 132 |
| 95 // TODO(erg): GTK theme the info bar. | 133 // TODO(erg): GTK theme the info bar. |
| 96 close_button_.reset(CustomDrawButton::CloseButton(NULL)); | 134 close_button_.reset(CustomDrawButton::CloseButton(NULL)); |
| 97 gtk_util::CenterWidgetInHBox(hbox_, close_button_->widget(), true, 0); | 135 gtk_util::CenterWidgetInHBox(hbox_, close_button_->widget(), true, 0); |
| 98 g_signal_connect(close_button_->widget(), "clicked", | 136 g_signal_connect(close_button_->widget(), "clicked", |
| 99 G_CALLBACK(OnCloseButton), this); | 137 G_CALLBACK(OnCloseButton), this); |
| 100 | 138 |
| 101 slide_widget_.reset(new SlideAnimatorGtk(border_bin_.get(), | 139 slide_widget_.reset(new SlideAnimatorGtk(border_bin_.get(), |
| 102 SlideAnimatorGtk::DOWN, | 140 SlideAnimatorGtk::DOWN, |
| 103 0, true, this)); | 141 0, true, this)); |
| 104 // We store a pointer back to |this| so we can refer to it from the infobar | 142 // We store a pointer back to |this| so we can refer to it from the infobar |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 info_bar->RemoveInfoBar(); | 193 info_bar->RemoveInfoBar(); |
| 156 } | 194 } |
| 157 | 195 |
| 158 // AlertInfoBar ---------------------------------------------------------------- | 196 // AlertInfoBar ---------------------------------------------------------------- |
| 159 | 197 |
| 160 class AlertInfoBar : public InfoBar { | 198 class AlertInfoBar : public InfoBar { |
| 161 public: | 199 public: |
| 162 AlertInfoBar(AlertInfoBarDelegate* delegate) | 200 AlertInfoBar(AlertInfoBarDelegate* delegate) |
| 163 : InfoBar(delegate) { | 201 : InfoBar(delegate) { |
| 164 std::wstring text = delegate->GetMessageText(); | 202 std::wstring text = delegate->GetMessageText(); |
| 165 GtkWidget* label = gtk_label_new(WideToUTF8(text).c_str()); | 203 label_ = gtk_label_new(WideToUTF8(text).c_str()); |
| 166 gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gfx::kGdkBlack); | 204 gtk_widget_modify_fg(label_, GTK_STATE_NORMAL, &(style_.text_color_)); |
| 167 gtk_box_pack_start(GTK_BOX(hbox_), label, FALSE, FALSE, 0); | 205 //gtk_box_pack_start(GTK_BOX(hbox_), label_, FALSE, FALSE, 0); |
| 206 gtk_util::CenterWidgetInHBox(hbox_, label_, false, 0); |
| 168 | 207 |
| 169 gtk_widget_show_all(border_bin_.get()); | 208 gtk_widget_show_all(border_bin_.get()); |
| 170 } | 209 } |
| 210 protected: |
| 211 // The label for the alert. |
| 212 GtkWidget* label_; |
| 171 }; | 213 }; |
| 172 | 214 |
| 173 // LinkInfoBar ----------------------------------------------------------------- | 215 // LinkInfoBar ----------------------------------------------------------------- |
| 174 | 216 |
| 175 class LinkInfoBar : public InfoBar { | 217 class LinkInfoBar : public InfoBar { |
| 176 public: | 218 public: |
| 177 LinkInfoBar(LinkInfoBarDelegate* delegate) | 219 LinkInfoBar(LinkInfoBarDelegate* delegate) |
| 178 : InfoBar(delegate) { | 220 : InfoBar(delegate) { |
| 179 size_t link_offset; | 221 size_t link_offset; |
| 180 std::wstring display_text = | 222 std::wstring display_text = |
| 181 delegate->GetMessageTextWithOffset(&link_offset); | 223 delegate->GetMessageTextWithOffset(&link_offset); |
| 182 std::wstring link_text = delegate->GetLinkText(); | 224 std::wstring link_text = delegate->GetLinkText(); |
| 183 | 225 |
| 184 // Create the link button. | 226 // Create the link button. |
| 185 GtkWidget* link_button = | 227 GtkWidget* link_button = |
| 186 gtk_chrome_link_button_new(WideToUTF8(link_text).c_str()); | 228 gtk_chrome_link_button_new(WideToUTF8(link_text).c_str()); |
| 187 gtk_chrome_link_button_set_use_gtk_theme( | 229 gtk_chrome_link_button_set_use_gtk_theme( |
| 188 GTK_CHROME_LINK_BUTTON(link_button), FALSE); | 230 GTK_CHROME_LINK_BUTTON(link_button), FALSE); |
| 189 g_signal_connect(link_button, "clicked", | 231 g_signal_connect(link_button, "clicked", |
| 190 G_CALLBACK(OnLinkClick), this); | 232 G_CALLBACK(OnLinkClick), this); |
| 191 gtk_util::SetButtonTriggersNavigation(link_button); | 233 gtk_util::SetButtonTriggersNavigation(link_button); |
| 192 | 234 |
| 193 // If link_offset is npos, we right-align the link instead of embedding it | 235 // If link_offset is npos, we right-align the link instead of embedding it |
| 194 // in the text. | 236 // in the text. |
| 195 if (link_offset == std::wstring::npos) { | 237 if (link_offset == std::wstring::npos) { |
| 196 gtk_box_pack_end(GTK_BOX(hbox_), link_button, FALSE, FALSE, 0); | 238 gtk_box_pack_end(GTK_BOX(hbox_), link_button, FALSE, FALSE, 0); |
| 197 GtkWidget* label = gtk_label_new(WideToUTF8(display_text).c_str()); | 239 GtkWidget* label = gtk_label_new(WideToUTF8(display_text).c_str()); |
| 198 gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gfx::kGdkBlack); | 240 gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &(style_.text_color_)); |
| 199 gtk_box_pack_start(GTK_BOX(hbox_), label, FALSE, FALSE, 0); | 241 gtk_box_pack_start(GTK_BOX(hbox_), label, FALSE, FALSE, 0); |
| 200 } else { | 242 } else { |
| 201 GtkWidget* initial_label = gtk_label_new( | 243 GtkWidget* initial_label = gtk_label_new( |
| 202 WideToUTF8(display_text.substr(0, link_offset)).c_str()); | 244 WideToUTF8(display_text.substr(0, link_offset)).c_str()); |
| 203 GtkWidget* trailing_label = gtk_label_new( | 245 GtkWidget* trailing_label = gtk_label_new( |
| 204 WideToUTF8(display_text.substr(link_offset)).c_str()); | 246 WideToUTF8(display_text.substr(link_offset)).c_str()); |
| 205 | 247 |
| 206 gtk_widget_modify_fg(initial_label, GTK_STATE_NORMAL, &gfx::kGdkBlack); | 248 gtk_widget_modify_fg(initial_label, |
| 207 gtk_widget_modify_fg(trailing_label, GTK_STATE_NORMAL, &gfx::kGdkBlack); | 249 GTK_STATE_NORMAL, |
| 250 &(style_.text_color_)); |
| 251 gtk_widget_modify_fg(trailing_label, |
| 252 GTK_STATE_NORMAL, |
| 253 &(style_.text_color_)); |
| 208 | 254 |
| 209 // We don't want any spacing between the elements, so we pack them into | 255 // We don't want any spacing between the elements, so we pack them into |
| 210 // this hbox that doesn't use kElementPadding. | 256 // this hbox that doesn't use kElementPadding. |
| 211 GtkWidget* hbox = gtk_hbox_new(FALSE, 0); | 257 GtkWidget* hbox = gtk_hbox_new(FALSE, 0); |
| 212 gtk_box_pack_start(GTK_BOX(hbox), initial_label, FALSE, FALSE, 0); | 258 gtk_box_pack_start(GTK_BOX(hbox), initial_label, FALSE, FALSE, 0); |
| 213 gtk_util::CenterWidgetInHBox(hbox, link_button, false, 0); | 259 gtk_util::CenterWidgetInHBox(hbox, link_button, false, 0); |
| 214 gtk_box_pack_start(GTK_BOX(hbox), trailing_label, FALSE, FALSE, 0); | 260 gtk_box_pack_start(GTK_BOX(hbox), trailing_label, FALSE, FALSE, 0); |
| 215 gtk_box_pack_start(GTK_BOX(hbox_), hbox, FALSE, FALSE, 0); | 261 gtk_box_pack_start(GTK_BOX(hbox_), hbox, FALSE, FALSE, 0); |
| 216 } | 262 } |
| 217 | 263 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 // doesn't specify a button of the given type. | 298 // doesn't specify a button of the given type. |
| 253 void AddConfirmButton(ConfirmInfoBarDelegate::InfoBarButton type) { | 299 void AddConfirmButton(ConfirmInfoBarDelegate::InfoBarButton type) { |
| 254 if (delegate_->AsConfirmInfoBarDelegate()->GetButtons() & type) { | 300 if (delegate_->AsConfirmInfoBarDelegate()->GetButtons() & type) { |
| 255 GtkWidget* button = gtk_button_new_with_label(WideToUTF8( | 301 GtkWidget* button = gtk_button_new_with_label(WideToUTF8( |
| 256 delegate_->AsConfirmInfoBarDelegate()->GetButtonLabel(type)).c_str()); | 302 delegate_->AsConfirmInfoBarDelegate()->GetButtonLabel(type)).c_str()); |
| 257 gtk_util::CenterWidgetInHBox(hbox_, button, true, 0); | 303 gtk_util::CenterWidgetInHBox(hbox_, button, true, 0); |
| 258 g_signal_connect(button, "clicked", | 304 g_signal_connect(button, "clicked", |
| 259 G_CALLBACK(type == ConfirmInfoBarDelegate::BUTTON_OK ? | 305 G_CALLBACK(type == ConfirmInfoBarDelegate::BUTTON_OK ? |
| 260 OnOkButton : OnCancelButton), | 306 OnOkButton : OnCancelButton), |
| 261 this); | 307 this); |
| 308 gtk_container_set_border_width(GTK_CONTAINER(button), 0); |
| 262 } | 309 } |
| 263 } | 310 } |
| 264 | 311 |
| 265 static void OnCancelButton(GtkWidget* button, ConfirmInfoBar* info_bar) { | 312 static void OnCancelButton(GtkWidget* button, ConfirmInfoBar* info_bar) { |
| 266 if (info_bar->delegate_->AsConfirmInfoBarDelegate()->Cancel()) | 313 if (info_bar->delegate_->AsConfirmInfoBarDelegate()->Cancel()) |
| 267 info_bar->RemoveInfoBar(); | 314 info_bar->RemoveInfoBar(); |
| 268 } | 315 } |
| 269 | 316 |
| 270 static void OnOkButton(GtkWidget* button, ConfirmInfoBar* info_bar) { | 317 static void OnOkButton(GtkWidget* button, ConfirmInfoBar* info_bar) { |
| 271 if (info_bar->delegate_->AsConfirmInfoBarDelegate()->Accept()) | 318 if (info_bar->delegate_->AsConfirmInfoBarDelegate()->Accept()) |
| 272 info_bar->RemoveInfoBar(); | 319 info_bar->RemoveInfoBar(); |
| 273 } | 320 } |
| 274 }; | 321 }; |
| 275 | 322 |
| 323 // GeolocInfoBar --------------------------------------------------------------- |
| 324 |
| 325 class GeolocInfoBar : public AlertInfoBar { |
| 326 public: |
| 327 GeolocInfoBar(GeolocInfoBarDelegate* delegate) |
| 328 : AlertInfoBar(delegate) { |
| 329 button_box_ = gtk_hbox_new(FALSE, kElementPadding); |
| 330 AddConfirmButton(ConfirmInfoBarDelegate::BUTTON_OK); |
| 331 AddConfirmButton(ConfirmInfoBarDelegate::BUTTON_CANCEL); |
| 332 gtk_box_pack_start(GTK_BOX(vbox_), button_box_, FALSE, FALSE, 0); |
| 333 |
| 334 std::wstring text = delegate->GetMessageText(); |
| 335 gtk_label_set_markup(GTK_LABEL(label_), WideToUTF8(text).c_str()); |
| 336 |
| 337 GtkWidget* linkbox = CreateLinkButtons(delegate); |
| 338 GtkWidget* checkbox = CreateRememberCheckbox(delegate); |
| 339 |
| 340 gtk_box_pack_start(GTK_BOX(button_box_), checkbox, FALSE, FALSE, 0); |
| 341 gtk_box_pack_end(GTK_BOX(button_box_), linkbox, FALSE, FALSE, 0); |
| 342 |
| 343 gtk_widget_show_all(border_bin_.get()); |
| 344 } |
| 345 |
| 346 private: |
| 347 GtkWidget* CreateLinkButtons(GeolocInfoBarDelegate* delegate) { |
| 348 std::wstring customize_text = delegate->GetCustomizeText(); |
| 349 std::wstring learn_more_text = delegate->GetLearnMoreText(); |
| 350 |
| 351 GtkWidget* linkbox = gtk_hbox_new(FALSE, kElementPadding); |
| 352 GtkWidget* customize_link = gtk_chrome_link_button_new_with_markup( |
| 353 WideToUTF8(customize_text).c_str()); |
| 354 GtkWidget* learn_more_link = gtk_chrome_link_button_new_with_markup( |
| 355 WideToUTF8(learn_more_text).c_str()); |
| 356 |
| 357 g_signal_connect(customize_link, "clicked", |
| 358 G_CALLBACK(OnCustomizeClick), this); |
| 359 g_signal_connect(learn_more_link, "clicked", |
| 360 G_CALLBACK(OnLearnMoreClick), this); |
| 361 |
| 362 gtk_box_pack_end(GTK_BOX(linkbox), customize_link, FALSE, FALSE, 0); |
| 363 gtk_box_pack_end(GTK_BOX(linkbox), learn_more_link, FALSE, FALSE, 0); |
| 364 return linkbox; |
| 365 } |
| 366 |
| 367 GtkWidget* CreateRememberCheckbox(GeolocInfoBarDelegate* delegate) { |
| 368 GtkWidget* checkbox = gtk_hbox_new(FALSE, kElementPadding); |
| 369 GtkWidget* check_button = gtk_check_button_new(); |
| 370 GtkWidget* remember = gtk_label_new("Remember for this site"); |
| 371 gtk_box_pack_start(GTK_BOX(checkbox), check_button, FALSE, FALSE, 0); |
| 372 gtk_box_pack_start(GTK_BOX(checkbox), remember, FALSE, FALSE, 0); |
| 373 gtk_widget_modify_fg(remember, GTK_STATE_NORMAL, &(style_.text_color_)); |
| 374 return checkbox; |
| 375 } |
| 376 |
| 377 // Adds a button to the info bar by type. It will do nothing if the delegate |
| 378 // doesn't specify a button of the given type. |
| 379 void AddConfirmButton(ConfirmInfoBarDelegate::InfoBarButton type) { |
| 380 GeolocInfoBarDelegate *delegate = delegate_->AsGeolocInfoBarDelegate(); |
| 381 if (delegate->GetButtons() & type) { |
| 382 GtkWidget* button = gtk_skinny_button_new_with_label(WideToUTF8( |
| 383 delegate->GetButtonLabel(type)).c_str()); |
| 384 gtk_util::CenterWidgetInHBox(button_box_, button, false, 0); |
| 385 g_signal_connect(button, "clicked", |
| 386 G_CALLBACK(type == ConfirmInfoBarDelegate::BUTTON_OK ? |
| 387 OnOkButton : OnCancelButton), |
| 388 this); |
| 389 } |
| 390 } |
| 391 |
| 392 static void OnCancelButton(GtkWidget* button, GeolocInfoBar* info_bar) { |
| 393 if (info_bar->delegate_->AsGeolocInfoBarDelegate()->Cancel()) |
| 394 info_bar->RemoveInfoBar(); |
| 395 } |
| 396 |
| 397 static void OnOkButton(GtkWidget* button, GeolocInfoBar* info_bar) { |
| 398 if (info_bar->delegate_->AsGeolocInfoBarDelegate()->Accept()) |
| 399 info_bar->RemoveInfoBar(); |
| 400 } |
| 401 |
| 402 |
| 403 |
| 404 private: |
| 405 static WindowOpenDisposition GetDisposition(GtkWidget* button) { |
| 406 const GdkEventButton* button_click_event = |
| 407 reinterpret_cast<GdkEventButton*>(gtk_get_current_event()); |
| 408 WindowOpenDisposition disposition = CURRENT_TAB; |
| 409 if (button_click_event) { |
| 410 disposition = event_utils::DispositionFromEventFlags( |
| 411 button_click_event->state); |
| 412 } |
| 413 return disposition; |
| 414 } |
| 415 static void OnCustomizeClick(GtkWidget* button, GeolocInfoBar* info_bar) { |
| 416 WindowOpenDisposition disposition = GetDisposition(button); |
| 417 if (info_bar->delegate_->AsGeolocInfoBarDelegate()-> |
| 418 CustomizeClicked(disposition)) { |
| 419 info_bar->RemoveInfoBar(); |
| 420 } |
| 421 } |
| 422 static void OnLearnMoreClick(GtkWidget* button, GeolocInfoBar* info_bar) { |
| 423 WindowOpenDisposition disposition = GetDisposition(button); |
| 424 if (info_bar->delegate_->AsGeolocInfoBarDelegate()-> |
| 425 LearnMoreClicked(disposition)) { |
| 426 info_bar->RemoveInfoBar(); |
| 427 } |
| 428 } |
| 429 |
| 430 // The hbox that holds the buttons. |
| 431 GtkWidget* button_box_; |
| 432 }; |
| 433 |
| 434 class CustomizeGeolocInfoBar : public AlertInfoBar { |
| 435 public: |
| 436 CustomizeGeolocInfoBar(CustomizeGeolocInfoBarDelegate* delegate) |
| 437 : AlertInfoBar(delegate) { |
| 438 std::wstring text = delegate->GetMessageText(); |
| 439 gtk_label_set_markup(GTK_LABEL(label_), WideToUTF8(text).c_str()); |
| 440 |
| 441 |
| 442 GtkWidget *hbox = gtk_hbox_new(FALSE, kElementPadding); |
| 443 text = delegate->GetAuxiliaryText(); |
| 444 GtkWidget *label = gtk_label_new(WideToUTF8(text).c_str()); |
| 445 gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &(style_.text_color_)); |
| 446 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); |
| 447 gtk_box_pack_start(GTK_BOX(vbox_), hbox, false, false, 0); |
| 448 |
| 449 button_box_ = gtk_hbox_new(FALSE, kElementPadding); |
| 450 AddCustomizeButton(CustomizeGeolocInfoBarDelegate::BUTTON_BEST); |
| 451 AddCustomizeButton(CustomizeGeolocInfoBarDelegate::BUTTON_CITY); |
| 452 AddCustomizeButton(CustomizeGeolocInfoBarDelegate::BUTTON_NONE); |
| 453 |
| 454 gtk_box_pack_start(GTK_BOX(vbox_), button_box_, FALSE, FALSE, kElementPaddin
g*2); |
| 455 |
| 456 GtkWidget* checkbox = CreateRememberCheckbox(delegate); |
| 457 gtk_box_pack_start(GTK_BOX(hbox), checkbox, FALSE, FALSE, 0); |
| 458 |
| 459 gtk_widget_show_all(border_bin_.get()); |
| 460 } |
| 461 |
| 462 private: |
| 463 // Adds a button to the info bar by type. It will do nothing if the delegate |
| 464 // doesn't specify a button of the given type. |
| 465 void AddCustomizeButton(CustomizeGeolocInfoBarDelegate::GeolocButton type) { |
| 466 GtkWidget* box = gtk_vbox_new(FALSE, kElementPadding); |
| 467 |
| 468 CustomizeGeolocInfoBarDelegate *delegate = |
| 469 delegate_->AsCustomizeGeolocInfoBarDelegate(); |
| 470 GtkWidget* button = gtk_button_new(); |
| 471 GtkWidget* label = gtk_label_new(WideToUTF8( |
| 472 delegate->GetGeolocButtonLabel(type)).c_str()); |
| 473 gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &(style_.text_color_)); |
| 474 |
| 475 SkBitmap* icon = delegate->GetGeolocButtonImage(type); |
| 476 if (icon) { |
| 477 GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(icon); |
| 478 gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_pixbuf(pixbuf)
); |
| 479 g_object_unref(pixbuf); |
| 480 } |
| 481 gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); |
| 482 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); |
| 483 |
| 484 gtk_box_pack_start(GTK_BOX(button_box_), box, true, FALSE, 0); |
| 485 ConnectButton(button, type); |
| 486 gtk_container_set_border_width(GTK_CONTAINER(button), 0); |
| 487 } |
| 488 |
| 489 GtkWidget* CreateRememberCheckbox(CustomizeGeolocInfoBarDelegate* delegate) { |
| 490 GtkWidget* checkbox = gtk_hbox_new(FALSE, kElementPadding); |
| 491 GtkWidget* check_button = gtk_check_button_new(); |
| 492 GtkWidget* remember = gtk_label_new("Remember for this site"); |
| 493 gtk_box_pack_start(GTK_BOX(checkbox), check_button, FALSE, FALSE, 0); |
| 494 gtk_box_pack_start(GTK_BOX(checkbox), remember, FALSE, FALSE, 0); |
| 495 gtk_widget_modify_fg(remember, GTK_STATE_NORMAL, &(style_.text_color_)); |
| 496 return checkbox; |
| 497 } |
| 498 |
| 499 void ConnectButton(GtkWidget *button, |
| 500 CustomizeGeolocInfoBarDelegate::GeolocButton type) { |
| 501 switch(type) { |
| 502 case CustomizeGeolocInfoBarDelegate::BUTTON_BEST: |
| 503 g_signal_connect(button, "clicked", G_CALLBACK(OnBestClick), this); |
| 504 break; |
| 505 case CustomizeGeolocInfoBarDelegate::BUTTON_CITY: |
| 506 g_signal_connect(button, "clicked", G_CALLBACK(OnCityClick), this); |
| 507 break; |
| 508 case CustomizeGeolocInfoBarDelegate::BUTTON_NONE: |
| 509 g_signal_connect(button, "clicked", G_CALLBACK(OnNoneClick), this); |
| 510 break; |
| 511 default: |
| 512 NOTREACHED(); |
| 513 break; |
| 514 } |
| 515 } |
| 516 |
| 517 static void OnBestClick(GtkWidget* button, CustomizeGeolocInfoBar* info_bar) { |
| 518 if (info_bar->delegate_->AsCustomizeGeolocInfoBarDelegate() |
| 519 ->OnGeolocButtonClick(CustomizeGeolocInfoBarDelegate::BUTTON_BEST)) |
| 520 info_bar->RemoveInfoBar(); |
| 521 } |
| 522 |
| 523 static void OnCityClick(GtkWidget* button, CustomizeGeolocInfoBar* info_bar) { |
| 524 if (info_bar->delegate_->AsCustomizeGeolocInfoBarDelegate() |
| 525 ->OnGeolocButtonClick(CustomizeGeolocInfoBarDelegate::BUTTON_CITY)) |
| 526 info_bar->RemoveInfoBar(); |
| 527 } |
| 528 |
| 529 static void OnNoneClick(GtkWidget* button, CustomizeGeolocInfoBar* info_bar) { |
| 530 if (info_bar->delegate_->AsCustomizeGeolocInfoBarDelegate() |
| 531 ->OnGeolocButtonClick(CustomizeGeolocInfoBarDelegate::BUTTON_NONE)) |
| 532 info_bar->RemoveInfoBar(); |
| 533 } |
| 534 |
| 535 // The hbox that holds the buttons. |
| 536 GtkWidget* button_box_; |
| 537 |
| 538 }; |
| 539 |
| 276 // AlertInfoBarDelegate, InfoBarDelegate overrides: ---------------------------- | 540 // AlertInfoBarDelegate, InfoBarDelegate overrides: ---------------------------- |
| 277 | 541 |
| 278 InfoBar* AlertInfoBarDelegate::CreateInfoBar() { | 542 InfoBar* AlertInfoBarDelegate::CreateInfoBar() { |
| 279 return new AlertInfoBar(this); | 543 return new AlertInfoBar(this); |
| 280 } | 544 } |
| 281 | 545 |
| 282 // LinkInfoBarDelegate, InfoBarDelegate overrides: ----------------------------- | 546 // LinkInfoBarDelegate, InfoBarDelegate overrides: ----------------------------- |
| 283 | 547 |
| 284 InfoBar* LinkInfoBarDelegate::CreateInfoBar() { | 548 InfoBar* LinkInfoBarDelegate::CreateInfoBar() { |
| 285 return new LinkInfoBar(this); | 549 return new LinkInfoBar(this); |
| 286 } | 550 } |
| 287 | 551 |
| 288 // ConfirmInfoBarDelegate, InfoBarDelegate overrides: -------------------------- | 552 // ConfirmInfoBarDelegate, InfoBarDelegate overrides: -------------------------- |
| 289 | 553 |
| 290 InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() { | 554 InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() { |
| 291 return new ConfirmInfoBar(this); | 555 return new ConfirmInfoBar(this); |
| 292 } | 556 } |
| 557 |
| 558 // GeolocInfoBarDelegate, InfoBarDelegate overrides: --------------------_------ |
| 559 |
| 560 InfoBar* GeolocInfoBarDelegate::CreateInfoBar() { |
| 561 return new GeolocInfoBar(this); |
| 562 } |
| 563 |
| 564 // CustomizeGeolocInfoBarDelegate, InfoBarDelegate overrides: ------------------ |
| 565 |
| 566 InfoBar* CustomizeGeolocInfoBarDelegate::CreateInfoBar() { |
| 567 return new CustomizeGeolocInfoBar(this); |
| 568 } |
| OLD | NEW |