172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/infobars/infobar_gtk.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <gtk/gtk.h>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
10513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/platform_util.h"
1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/browser_window_gtk.h"
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/custom_button.h"
1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/gtk_chrome_link_button.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/gtk/gtk_theme_service.h"
1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/gtk_util.h"
1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/infobars/infobar_container_gtk.h"
17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/common/notification_service.h"
1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/gtk_util.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickextern const int InfoBar::kInfoBarHeight = 37;
21731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Pixels between infobar elements.
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kElementPadding = 5;
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Extra padding on either end of info bar.
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kLeftPadding = 5;
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kRightPadding = 5;
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// static
34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst int InfoBar::kEndOfLabelSpacing = 6;
35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst int InfoBar::kButtonButtonSpacing = 3;
36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochInfoBar::InfoBar(InfoBarDelegate* delegate)
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : container_(NULL),
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      delegate_(delegate),
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      theme_service_(NULL),
41513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      arrow_model_(this) {
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create |hbox_| and pad the sides.
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  hbox_ = gtk_hbox_new(FALSE, kElementPadding);
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make the whole infor bar horizontally shrinkable.
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_widget_set_size_request(hbox_, 0, -1);
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1);
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_alignment_set_padding(GTK_ALIGNMENT(padding),
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      0, 0, kLeftPadding, kRightPadding);
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
52513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bg_box_ = gtk_event_box_new();
53513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  gtk_widget_set_app_paintable(bg_box_, TRUE);
54513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  g_signal_connect(bg_box_, "expose-event",
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   G_CALLBACK(OnBackgroundExposeThunk), this);
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_container_add(GTK_CONTAINER(padding), hbox_);
57513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  gtk_container_add(GTK_CONTAINER(bg_box_), padding);
58513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  gtk_widget_set_size_request(bg_box_, -1, kInfoBarHeight);
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add the icon on the left, if any.
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SkBitmap* icon = delegate->GetIcon();
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (icon) {
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(icon);
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf);
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    g_object_unref(pixbuf);
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    gtk_misc_set_alignment(GTK_MISC(image), 0.5, 0.5);
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gtk_box_pack_start(GTK_BOX(hbox_), image, FALSE, FALSE, 0);
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  close_button_.reset(CustomDrawButton::CloseButton(NULL));
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_util::CenterWidgetInHBox(hbox_, close_button_->widget(), true, 0);
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_signal_connect(close_button_->widget(), "clicked",
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   G_CALLBACK(OnCloseButtonThunk), this);
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
77513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  slide_widget_.reset(new SlideAnimatorGtk(bg_box_,
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           SlideAnimatorGtk::DOWN,
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           0, true, true, this));
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We store a pointer back to |this| so we can refer to it from the infobar
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // container.
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_object_set_data(G_OBJECT(slide_widget_->widget()), "info-bar", this);
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochInfoBar::~InfoBar() {
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGtkWidget* InfoBar::widget() {
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return slide_widget_->widget();
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InfoBar::AnimateOpen() {
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  slide_widget_->Open();
94513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
95513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  gtk_widget_show_all(bg_box_);
96513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (bg_box_->window)
97513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    gdk_window_lower(bg_box_->window);
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InfoBar::Open() {
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  slide_widget_->OpenWithoutAnimation();
102513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
103513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  gtk_widget_show_all(bg_box_);
104513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (bg_box_->window)
105513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    gdk_window_lower(bg_box_->window);
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InfoBar::AnimateClose() {
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  slide_widget_->Close();
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InfoBar::Close() {
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (delegate_) {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delegate_->InfoBarClosed();
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delegate_ = NULL;
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete this;
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool InfoBar::IsAnimating() {
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return slide_widget_->IsAnimating();
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
124513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool InfoBar::IsClosing() {
125513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  return slide_widget_->IsClosing();
126513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
127513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
128513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid InfoBar::ShowArrowFor(InfoBar* other, bool animate) {
129513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  arrow_model_.ShowArrowFor(other, animate);
130513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
131513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
132513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid InfoBar::PaintStateChanged() {
133513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  gtk_widget_queue_draw(widget());
134513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
135513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InfoBar::RemoveInfoBar() const {
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  container_->RemoveDelegate(delegate_);
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InfoBar::Closed() {
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Close();
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid InfoBar::SetThemeProvider(GtkThemeService* theme_service) {
145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (theme_service_) {
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  theme_service_ = theme_service;
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateBorderColor();
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InfoBar::Observe(NotificationType type,
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      const NotificationSource& source,
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      const NotificationDetails& details) {
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateBorderColor();
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid InfoBar::AddLabelWithInlineLink(const string16& display_text,
1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                     const string16& link_text,
1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                     size_t link_offset,
1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                     GCallback callback) {
1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GtkWidget* link_button = gtk_chrome_link_button_new(
1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      UTF16ToUTF8(link_text).c_str());
1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  gtk_chrome_link_button_set_use_gtk_theme(
1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      GTK_CHROME_LINK_BUTTON(link_button), FALSE);
170513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  gtk_util::ForceFontSizePixels(
171513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      GTK_CHROME_LINK_BUTTON(link_button)->label, 13.4);
1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(callback);
1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  g_signal_connect(link_button, "clicked", callback, this);
1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  gtk_util::SetButtonTriggersNavigation(link_button);
1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // We want the link to be horizontally shrinkable, so that the Chrome
1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // window can be resized freely even with a very long link.
1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  gtk_widget_set_size_request(hbox, 0, -1);
1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  gtk_box_pack_start(GTK_BOX(hbox_), hbox, TRUE, TRUE, 0);
1813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Need to insert the link inside the display text.
1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GtkWidget* initial_label = gtk_label_new(
1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      UTF16ToUTF8(display_text.substr(0, link_offset)).c_str());
1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GtkWidget* trailing_label = gtk_label_new(
1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      UTF16ToUTF8(display_text.substr(link_offset)).c_str());
1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
188513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  gtk_util::ForceFontSizePixels(initial_label, 13.4);
189513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  gtk_util::ForceFontSizePixels(trailing_label, 13.4);
190513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // TODO(joth): None of the label widgets are set as shrinkable here, meaning
19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // the text will run under the close button etc. when the width is restricted,
19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // rather than eliding.
194513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  gtk_widget_modify_fg(initial_label, GTK_STATE_NORMAL, &gtk_util::kGdkBlack);
195513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  gtk_widget_modify_fg(trailing_label, GTK_STATE_NORMAL, &gtk_util::kGdkBlack);
1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // We don't want any spacing between the elements, so we pack them into
1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // this hbox that doesn't use kElementPadding.
1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  gtk_box_pack_start(GTK_BOX(hbox), initial_label, FALSE, FALSE, 0);
2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  gtk_util::CenterWidgetInHBox(hbox, link_button, false, 0);
2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  gtk_box_pack_start(GTK_BOX(hbox), trailing_label, FALSE, FALSE, 0);
2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InfoBar::GetTopColor(InfoBarDelegate::Type type,
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          double* r, double* g, double *b) {
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // These constants are copied from corresponding skia constants from
20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // browser/ui/views/infobars/infobars.cc, and then changed into 0-1 ranged
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // values for cairo.
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (type) {
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case InfoBarDelegate::WARNING_TYPE:
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *r = 255.0 / 255.0;
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *g = 242.0 / 255.0;
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *b = 183.0 / 255.0;
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case InfoBarDelegate::PAGE_ACTION_TYPE:
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *r = 218.0 / 255.0;
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *g = 231.0 / 255.0;
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *b = 249.0 / 255.0;
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InfoBar::GetBottomColor(InfoBarDelegate::Type type,
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             double* r, double* g, double *b) {
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (type) {
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case InfoBarDelegate::WARNING_TYPE:
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *r = 250.0 / 255.0;
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *g = 230.0 / 255.0;
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *b = 145.0 / 255.0;
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case InfoBarDelegate::PAGE_ACTION_TYPE:
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *r = 179.0 / 255.0;
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *g = 202.0 / 255.0;
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *b = 231.0 / 255.0;
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InfoBar::UpdateBorderColor() {
240513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  gtk_widget_queue_draw(widget());
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InfoBar::OnCloseButton(GtkWidget* button) {
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (delegate_)
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delegate_->InfoBarDismissed();
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RemoveInfoBar();
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
249513209b27ff55e2841eac0e4120199c23acce758Ben Murdochgboolean InfoBar::OnBackgroundExpose(GtkWidget* sender,
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     GdkEventExpose* event) {
251513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const int height = sender->allocation.height;
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
253513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(sender->window));
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gdk_cairo_rectangle(cr, &event->area);
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cairo_clip(cr);
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cairo_pattern_t* pattern = cairo_pattern_create_linear(0, 0, 0, height);
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  double top_r, top_g, top_b;
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GetTopColor(delegate_->GetInfoBarType(), &top_r, &top_g, &top_b);
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cairo_pattern_add_color_stop_rgb(pattern, 0.0, top_r, top_g, top_b);
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  double bottom_r, bottom_g, bottom_b;
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GetBottomColor(delegate_->GetInfoBarType(), &bottom_r, &bottom_g, &bottom_b);
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cairo_pattern_add_color_stop_rgb(
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      pattern, 1.0, bottom_r, bottom_g, bottom_b);
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cairo_set_source(cr, pattern);
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cairo_paint(cr);
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cairo_pattern_destroy(pattern);
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
271513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Draw the bottom border.
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GdkColor border_color = theme_service_->GetBorderColor();
273513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  cairo_set_source_rgb(cr, border_color.red / 65535.0,
274513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                           border_color.green / 65535.0,
275513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                           border_color.blue / 65535.0);
276513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  cairo_set_line_width(cr, 1.0);
277513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  int y = sender->allocation.height;
278513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  cairo_move_to(cr, 0, y - 0.5);
279513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  cairo_rel_line_to(cr, sender->allocation.width, 0);
280513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  cairo_stroke(cr);
281513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cairo_destroy(cr);
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
284513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (!arrow_model_.NeedToDrawInfoBarArrow())
285513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return FALSE;
286513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
287513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  GtkWindow* parent = platform_util::GetTopLevel(widget());
288513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  BrowserWindowGtk* browser_window =
289513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      BrowserWindowGtk::GetBrowserWindowForNativeWindow(parent);
290513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  int x = browser_window ?
291513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      browser_window->GetXPositionOfLocationIcon(sender) : 0;
292513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  size_t size = InfoBarArrowModel::kDefaultArrowSize;
294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  gfx::Rect arrow_bounds(x - size, y - size, 2 * size, size);
295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  arrow_model_.Paint(sender, event, arrow_bounds, border_color);
296513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return FALSE;
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
299