OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/ui/gtk/infobars/infobar_gtk.h" | 5 #include "chrome/browser/ui/gtk/infobars/infobar_gtk.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
9 #include "chrome/browser/infobars/infobar_service.h" | 9 #include "chrome/browser/infobars/infobar_service.h" |
10 #include "chrome/browser/profiles/profile.h" | 10 #include "chrome/browser/profiles/profile.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 const int InfoBar::kMaximumArrowTargetHeight = 24; | 45 const int InfoBar::kMaximumArrowTargetHeight = 24; |
46 const int InfoBar::kDefaultArrowTargetHalfWidth = kDefaultArrowTargetHeight; | 46 const int InfoBar::kDefaultArrowTargetHalfWidth = kDefaultArrowTargetHeight; |
47 const int InfoBar::kMaximumArrowTargetHalfWidth = 14; | 47 const int InfoBar::kMaximumArrowTargetHalfWidth = 14; |
48 const int InfoBar::kDefaultBarTargetHeight = 36; | 48 const int InfoBar::kDefaultBarTargetHeight = 36; |
49 | 49 |
50 // static | 50 // static |
51 const int InfoBarGtk::kEndOfLabelSpacing = 6; | 51 const int InfoBarGtk::kEndOfLabelSpacing = 6; |
52 | 52 |
53 InfoBarGtk::InfoBarGtk(InfoBarService* owner, InfoBarDelegate* delegate) | 53 InfoBarGtk::InfoBarGtk(InfoBarService* owner, InfoBarDelegate* delegate) |
54 : InfoBar(owner, delegate), | 54 : InfoBar(owner, delegate), |
55 theme_service_(GtkThemeService::GetFrom(Profile::FromBrowserContext( | 55 bg_box_(NULL), |
56 owner->GetWebContents()->GetBrowserContext()))), | 56 hbox_(NULL), |
| 57 theme_service_(NULL), |
57 signals_(new ui::GtkSignalRegistrar) { | 58 signals_(new ui::GtkSignalRegistrar) { |
58 DCHECK(delegate); | 59 } |
| 60 |
| 61 InfoBarGtk::~InfoBarGtk() { |
| 62 } |
| 63 |
| 64 void InfoBarGtk::InitWidgets() { |
| 65 DCHECK(owner()); |
| 66 DCHECK(!theme_service_); |
| 67 theme_service_ = GtkThemeService::GetFrom(Profile::FromBrowserContext( |
| 68 owner()->GetWebContents()->GetBrowserContext())); |
| 69 |
59 // Create |hbox_| and pad the sides. | 70 // Create |hbox_| and pad the sides. |
60 hbox_ = gtk_hbox_new(FALSE, kElementPadding); | 71 hbox_ = gtk_hbox_new(FALSE, kElementPadding); |
61 | 72 |
62 // Make the whole infor bar horizontally shrinkable. | 73 // Make the whole infor bar horizontally shrinkable. |
63 gtk_widget_set_size_request(hbox_, 0, -1); | 74 gtk_widget_set_size_request(hbox_, 0, -1); |
64 | 75 |
65 GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1); | 76 GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1); |
66 gtk_alignment_set_padding(GTK_ALIGNMENT(padding), | 77 gtk_alignment_set_padding(GTK_ALIGNMENT(padding), |
67 0, 0, kLeftPadding, kRightPadding); | 78 0, 0, kLeftPadding, kRightPadding); |
68 | 79 |
69 bg_box_ = gtk_event_box_new(); | 80 bg_box_ = gtk_event_box_new(); |
70 gtk_widget_set_app_paintable(bg_box_, TRUE); | 81 gtk_widget_set_app_paintable(bg_box_, TRUE); |
71 g_signal_connect(bg_box_, "expose-event", | 82 g_signal_connect(bg_box_, "expose-event", |
72 G_CALLBACK(OnBackgroundExposeThunk), this); | 83 G_CALLBACK(OnBackgroundExposeThunk), this); |
73 gtk_container_add(GTK_CONTAINER(padding), hbox_); | 84 gtk_container_add(GTK_CONTAINER(padding), hbox_); |
74 gtk_container_add(GTK_CONTAINER(bg_box_), padding); | 85 gtk_container_add(GTK_CONTAINER(bg_box_), padding); |
75 | 86 |
76 // Add the icon on the left, if any. | 87 // Add the icon on the left, if any. |
77 gfx::Image* icon = delegate->GetIcon(); | 88 gfx::Image* icon = delegate()->GetIcon(); |
78 if (icon) { | 89 if (icon) { |
79 GtkWidget* image = gtk_image_new_from_pixbuf(icon->ToGdkPixbuf()); | 90 GtkWidget* image = gtk_image_new_from_pixbuf(icon->ToGdkPixbuf()); |
80 | 91 |
81 gtk_misc_set_alignment(GTK_MISC(image), 0.5, 0.5); | 92 gtk_misc_set_alignment(GTK_MISC(image), 0.5, 0.5); |
82 | 93 |
83 gtk_box_pack_start(GTK_BOX(hbox_), image, FALSE, FALSE, 0); | 94 gtk_box_pack_start(GTK_BOX(hbox_), image, FALSE, FALSE, 0); |
84 } | 95 } |
85 | 96 |
86 close_button_.reset(CustomDrawButton::CloseButtonBar(theme_service_)); | 97 close_button_.reset(CustomDrawButton::CloseButtonBar(theme_service_)); |
87 gtk_util::CenterWidgetInHBox(hbox_, close_button_->widget(), true, 0); | 98 gtk_util::CenterWidgetInHBox(hbox_, close_button_->widget(), true, 0); |
88 signals_->Connect(close_button_->widget(), "clicked", | 99 signals_->Connect(close_button_->widget(), "clicked", |
89 G_CALLBACK(OnCloseButtonThunk), this); | 100 G_CALLBACK(OnCloseButtonThunk), this); |
90 | 101 |
91 widget_.Own(gtk_expanded_container_new()); | 102 widget_.Own(gtk_expanded_container_new()); |
92 gtk_container_add(GTK_CONTAINER(widget_.get()), bg_box_); | 103 gtk_container_add(GTK_CONTAINER(widget_.get()), bg_box_); |
93 gtk_widget_set_size_request(widget_.get(), -1, 0); | 104 gtk_widget_set_size_request(widget_.get(), -1, 0); |
94 | 105 |
95 g_signal_connect(widget_.get(), "child-size-request", | 106 g_signal_connect(widget_.get(), "child-size-request", |
96 G_CALLBACK(OnChildSizeRequestThunk), | 107 G_CALLBACK(OnChildSizeRequestThunk), |
97 this); | 108 this); |
98 | 109 |
99 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED, | 110 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED, |
100 content::Source<ThemeService>(theme_service_)); | 111 content::Source<ThemeService>(theme_service_)); |
101 UpdateBorderColor(); | 112 UpdateBorderColor(); |
102 } | 113 } |
103 | 114 |
104 InfoBarGtk::~InfoBarGtk() { | |
105 } | |
106 | |
107 GtkWidget* InfoBarGtk::widget() { | 115 GtkWidget* InfoBarGtk::widget() { |
108 return widget_.get(); | 116 return widget_.get(); |
109 } | 117 } |
110 | 118 |
111 GdkColor InfoBarGtk::GetBorderColor() const { | 119 GdkColor InfoBarGtk::GetBorderColor() const { |
| 120 DCHECK(theme_service_); |
112 return theme_service_->GetBorderColor(); | 121 return theme_service_->GetBorderColor(); |
113 } | 122 } |
114 | 123 |
115 int InfoBarGtk::AnimatingHeight() const { | 124 int InfoBarGtk::AnimatingHeight() const { |
116 return animation().is_animating() ? bar_target_height() : 0; | 125 return animation().is_animating() ? bar_target_height() : 0; |
117 } | 126 } |
118 | 127 |
119 ui::GtkSignalRegistrar* InfoBarGtk::Signals() { | 128 ui::GtkSignalRegistrar* InfoBarGtk::Signals() { |
120 return signals_.get(); | 129 return signals_.get(); |
121 } | 130 } |
122 | 131 |
123 GtkWidget* InfoBarGtk::CreateLabel(const std::string& text) { | 132 GtkWidget* InfoBarGtk::CreateLabel(const std::string& text) { |
| 133 DCHECK(theme_service_); |
124 return theme_service_->BuildLabel(text, ui::kGdkBlack); | 134 return theme_service_->BuildLabel(text, ui::kGdkBlack); |
125 } | 135 } |
126 | 136 |
127 GtkWidget* InfoBarGtk::CreateLinkButton(const std::string& text) { | 137 GtkWidget* InfoBarGtk::CreateLinkButton(const std::string& text) { |
| 138 DCHECK(theme_service_); |
128 return theme_service_->BuildChromeLinkButton(text); | 139 return theme_service_->BuildChromeLinkButton(text); |
129 } | 140 } |
130 | 141 |
131 // static | 142 // static |
132 GtkWidget* InfoBarGtk::CreateMenuButton(const std::string& text) { | 143 GtkWidget* InfoBarGtk::CreateMenuButton(const std::string& text) { |
133 GtkWidget* button = gtk_button_new(); | 144 GtkWidget* button = gtk_button_new(); |
134 GtkWidget* former_child = gtk_bin_get_child(GTK_BIN(button)); | 145 GtkWidget* former_child = gtk_bin_get_child(GTK_BIN(button)); |
135 if (former_child) | 146 if (former_child) |
136 gtk_container_remove(GTK_CONTAINER(button), former_child); | 147 gtk_container_remove(GTK_CONTAINER(button), former_child); |
137 | 148 |
(...skipping 13 matching lines...) Expand all Loading... |
151 SkColor InfoBarGtk::ConvertGetColor(ColorGetter getter) { | 162 SkColor InfoBarGtk::ConvertGetColor(ColorGetter getter) { |
152 double r, g, b; | 163 double r, g, b; |
153 (this->*getter)(delegate()->GetInfoBarType(), &r, &g, &b); | 164 (this->*getter)(delegate()->GetInfoBarType(), &r, &g, &b); |
154 return SkColorSetARGB(255, 255 * r, 255 * g, 255 * b); | 165 return SkColorSetARGB(255, 255 * r, 255 * g, 255 * b); |
155 } | 166 } |
156 | 167 |
157 void InfoBarGtk::AddLabelWithInlineLink(const string16& display_text, | 168 void InfoBarGtk::AddLabelWithInlineLink(const string16& display_text, |
158 const string16& link_text, | 169 const string16& link_text, |
159 size_t link_offset, | 170 size_t link_offset, |
160 GCallback callback) { | 171 GCallback callback) { |
| 172 DCHECK(hbox_); |
161 GtkWidget* link_button = CreateLinkButton(UTF16ToUTF8(link_text)); | 173 GtkWidget* link_button = CreateLinkButton(UTF16ToUTF8(link_text)); |
162 gtk_util::ForceFontSizePixels( | 174 gtk_util::ForceFontSizePixels( |
163 GTK_CHROME_LINK_BUTTON(link_button)->label, 13.4); | 175 GTK_CHROME_LINK_BUTTON(link_button)->label, 13.4); |
164 DCHECK(callback); | 176 DCHECK(callback); |
165 signals_->Connect(link_button, "clicked", callback, this); | 177 signals_->Connect(link_button, "clicked", callback, this); |
166 gtk_util::SetButtonTriggersNavigation(link_button); | 178 gtk_util::SetButtonTriggersNavigation(link_button); |
167 | 179 |
168 GtkWidget* hbox = gtk_hbox_new(FALSE, 0); | 180 GtkWidget* hbox = gtk_hbox_new(FALSE, 0); |
169 // We want the link to be horizontally shrinkable, so that the Chrome | 181 // We want the link to be horizontally shrinkable, so that the Chrome |
170 // window can be resized freely even with a very long link. | 182 // window can be resized freely even with a very long link. |
(...skipping 22 matching lines...) Expand all Loading... |
193 | 205 |
194 void InfoBarGtk::ShowMenuWithModel(GtkWidget* sender, | 206 void InfoBarGtk::ShowMenuWithModel(GtkWidget* sender, |
195 MenuGtk::Delegate* delegate, | 207 MenuGtk::Delegate* delegate, |
196 ui::MenuModel* model) { | 208 ui::MenuModel* model) { |
197 menu_.reset(new MenuGtk(delegate, model)); | 209 menu_.reset(new MenuGtk(delegate, model)); |
198 menu_->PopupForWidget(sender, 1, gtk_get_current_event_time()); | 210 menu_->PopupForWidget(sender, 1, gtk_get_current_event_time()); |
199 } | 211 } |
200 | 212 |
201 void InfoBarGtk::GetTopColor(InfoBarDelegate::Type type, | 213 void InfoBarGtk::GetTopColor(InfoBarDelegate::Type type, |
202 double* r, double* g, double* b) { | 214 double* r, double* g, double* b) { |
| 215 DCHECK(theme_service_); |
203 SkColor color = theme_service_->UsingNativeTheme() ? | 216 SkColor color = theme_service_->UsingNativeTheme() ? |
204 theme_service_->GetColor(ThemeProperties::COLOR_TOOLBAR) : | 217 theme_service_->GetColor(ThemeProperties::COLOR_TOOLBAR) : |
205 GetInfoBarTopColor(type); | 218 GetInfoBarTopColor(type); |
206 *r = SkColorGetR(color) / 255.0; | 219 *r = SkColorGetR(color) / 255.0; |
207 *g = SkColorGetG(color) / 255.0; | 220 *g = SkColorGetG(color) / 255.0; |
208 *b = SkColorGetB(color) / 255.0; | 221 *b = SkColorGetB(color) / 255.0; |
209 } | 222 } |
210 | 223 |
211 void InfoBarGtk::GetBottomColor(InfoBarDelegate::Type type, | 224 void InfoBarGtk::GetBottomColor(InfoBarDelegate::Type type, |
212 double* r, double* g, double* b) { | 225 double* r, double* g, double* b) { |
| 226 DCHECK(theme_service_); |
213 SkColor color = theme_service_->UsingNativeTheme() ? | 227 SkColor color = theme_service_->UsingNativeTheme() ? |
214 theme_service_->GetColor(ThemeProperties::COLOR_TOOLBAR) : | 228 theme_service_->GetColor(ThemeProperties::COLOR_TOOLBAR) : |
215 GetInfoBarBottomColor(type); | 229 GetInfoBarBottomColor(type); |
216 *r = SkColorGetR(color) / 255.0; | 230 *r = SkColorGetR(color) / 255.0; |
217 *g = SkColorGetG(color) / 255.0; | 231 *g = SkColorGetG(color) / 255.0; |
218 *b = SkColorGetB(color) / 255.0; | 232 *b = SkColorGetB(color) / 255.0; |
219 } | 233 } |
220 | 234 |
221 void InfoBarGtk::UpdateBorderColor() { | 235 void InfoBarGtk::UpdateBorderColor() { |
| 236 DCHECK(widget()); |
222 gtk_widget_queue_draw(widget()); | 237 gtk_widget_queue_draw(widget()); |
223 } | 238 } |
224 | 239 |
225 void InfoBarGtk::OnCloseButton(GtkWidget* button) { | 240 void InfoBarGtk::OnCloseButton(GtkWidget* button) { |
226 // If we're not owned, we're already closing, so don't call | 241 // If we're not owned, we're already closing, so don't call |
227 // InfoBarDismissed(), since this can lead to us double-recording dismissals. | 242 // InfoBarDismissed(), since this can lead to us double-recording dismissals. |
228 if (delegate() && owned()) | 243 if (delegate() && owner()) |
229 delegate()->InfoBarDismissed(); | 244 delegate()->InfoBarDismissed(); |
230 RemoveSelf(); | 245 RemoveSelf(); |
231 } | 246 } |
232 | 247 |
233 gboolean InfoBarGtk::OnBackgroundExpose(GtkWidget* sender, | 248 gboolean InfoBarGtk::OnBackgroundExpose(GtkWidget* sender, |
234 GdkEventExpose* event) { | 249 GdkEventExpose* event) { |
235 TRACE_EVENT0("ui::gtk", "InfoBarGtk::OnBackgroundExpose"); | 250 TRACE_EVENT0("ui::gtk", "InfoBarGtk::OnBackgroundExpose"); |
| 251 DCHECK(theme_service_); |
236 | 252 |
237 GtkAllocation allocation; | 253 GtkAllocation allocation; |
238 gtk_widget_get_allocation(sender, &allocation); | 254 gtk_widget_get_allocation(sender, &allocation); |
239 const int height = allocation.height; | 255 const int height = allocation.height; |
240 | 256 |
241 cairo_t* cr = gdk_cairo_create(gtk_widget_get_window(sender)); | 257 cairo_t* cr = gdk_cairo_create(gtk_widget_get_window(sender)); |
242 gdk_cairo_rectangle(cr, &event->area); | 258 gdk_cairo_rectangle(cr, &event->area); |
243 cairo_clip(cr); | 259 cairo_clip(cr); |
244 | 260 |
245 cairo_pattern_t* pattern = cairo_pattern_create_linear(0, 0, 0, height); | 261 cairo_pattern_t* pattern = cairo_pattern_create_linear(0, 0, 0, height); |
(...skipping 24 matching lines...) Expand all Loading... |
270 | 286 |
271 if (container()) { | 287 if (container()) { |
272 static_cast<InfoBarContainerGtk*>(container())-> | 288 static_cast<InfoBarContainerGtk*>(container())-> |
273 PaintInfobarBitsOn(sender, event, this); | 289 PaintInfobarBitsOn(sender, event, this); |
274 } | 290 } |
275 | 291 |
276 return FALSE; | 292 return FALSE; |
277 } | 293 } |
278 | 294 |
279 void InfoBarGtk::PlatformSpecificShow(bool animate) { | 295 void InfoBarGtk::PlatformSpecificShow(bool animate) { |
| 296 DCHECK(bg_box_); |
| 297 |
| 298 DCHECK(widget()); |
280 gtk_widget_show_all(widget_.get()); | 299 gtk_widget_show_all(widget_.get()); |
281 gtk_widget_set_size_request(widget_.get(), -1, bar_height()); | 300 gtk_widget_set_size_request(widget_.get(), -1, bar_height()); |
282 | 301 |
283 GdkWindow* gdk_window = gtk_widget_get_window(bg_box_); | 302 GdkWindow* gdk_window = gtk_widget_get_window(bg_box_); |
284 if (gdk_window) | 303 if (gdk_window) |
285 gdk_window_lower(gdk_window); | 304 gdk_window_lower(gdk_window); |
286 } | 305 } |
287 | 306 |
288 void InfoBarGtk::PlatformSpecificOnCloseSoon() { | 307 void InfoBarGtk::PlatformSpecificOnCloseSoon() { |
289 // We must close all menus and prevent any signals from being emitted while | 308 // We must close all menus and prevent any signals from being emitted while |
290 // we are animating the info bar closed. | 309 // we are animating the info bar closed. |
291 menu_.reset(); | 310 menu_.reset(); |
292 signals_.reset(); | 311 signals_.reset(); |
293 } | 312 } |
294 | 313 |
295 void InfoBarGtk::PlatformSpecificOnHeightsRecalculated() { | 314 void InfoBarGtk::PlatformSpecificOnHeightsRecalculated() { |
| 315 DCHECK(bg_box_); |
| 316 DCHECK(widget()); |
296 gtk_widget_set_size_request(bg_box_, -1, bar_target_height()); | 317 gtk_widget_set_size_request(bg_box_, -1, bar_target_height()); |
297 gtk_expanded_container_move(GTK_EXPANDED_CONTAINER(widget_.get()), | 318 gtk_expanded_container_move(GTK_EXPANDED_CONTAINER(widget_.get()), |
298 bg_box_, 0, | 319 bg_box_, 0, |
299 bar_height() - bar_target_height()); | 320 bar_height() - bar_target_height()); |
300 | 321 |
301 gtk_widget_set_size_request(widget_.get(), -1, bar_height()); | 322 gtk_widget_set_size_request(widget_.get(), -1, bar_height()); |
302 gtk_widget_queue_draw(widget_.get()); | 323 gtk_widget_queue_draw(widget_.get()); |
303 } | 324 } |
304 | 325 |
305 void InfoBarGtk::Observe(int type, | 326 void InfoBarGtk::Observe(int type, |
306 const content::NotificationSource& source, | 327 const content::NotificationSource& source, |
307 const content::NotificationDetails& details) { | 328 const content::NotificationDetails& details) { |
| 329 DCHECK(widget()); |
308 UpdateBorderColor(); | 330 UpdateBorderColor(); |
309 } | 331 } |
310 | 332 |
311 void InfoBarGtk::OnChildSizeRequest(GtkWidget* expanded, | 333 void InfoBarGtk::OnChildSizeRequest(GtkWidget* expanded, |
312 GtkWidget* child, | 334 GtkWidget* child, |
313 GtkRequisition* requisition) { | 335 GtkRequisition* requisition) { |
314 requisition->height = -1; | 336 requisition->height = -1; |
315 } | 337 } |
OLD | NEW |