OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/notifications/balloon_view_gtk.h" | 5 #include "chrome/browser/ui/gtk/notifications/balloon_view_gtk.h" |
6 | 6 |
7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 frame_container_ = gtk_window_new(GTK_WINDOW_POPUP); | 207 frame_container_ = gtk_window_new(GTK_WINDOW_POPUP); |
208 | 208 |
209 // Construct the options menu. | 209 // Construct the options menu. |
210 options_menu_model_.reset(new NotificationOptionsMenuModel(balloon_)); | 210 options_menu_model_.reset(new NotificationOptionsMenuModel(balloon_)); |
211 options_menu_.reset(new MenuGtk(this, options_menu_model_.get())); | 211 options_menu_.reset(new MenuGtk(this, options_menu_model_.get())); |
212 | 212 |
213 // Create a BalloonViewHost to host the HTML contents of this balloon. | 213 // Create a BalloonViewHost to host the HTML contents of this balloon. |
214 html_contents_.reset(new BalloonViewHost(balloon)); | 214 html_contents_.reset(new BalloonViewHost(balloon)); |
215 html_contents_->Init(); | 215 html_contents_->Init(); |
216 gfx::NativeView contents = html_contents_->native_view(); | 216 gfx::NativeView contents = html_contents_->native_view(); |
| 217 g_signal_connect_after(contents, "expose-event", |
| 218 G_CALLBACK(OnContentsExposeThunk), this); |
217 | 219 |
218 // Divide the frame vertically into the shelf and the content area. | 220 // Divide the frame vertically into the shelf and the content area. |
219 GtkWidget* vbox = gtk_vbox_new(0, 0); | 221 GtkWidget* vbox = gtk_vbox_new(0, 0); |
220 gtk_container_add(GTK_CONTAINER(frame_container_), vbox); | 222 gtk_container_add(GTK_CONTAINER(frame_container_), vbox); |
221 | 223 |
222 shelf_ = gtk_hbox_new(0, 0); | 224 shelf_ = gtk_hbox_new(0, 0); |
223 gtk_container_add(GTK_CONTAINER(vbox), shelf_); | 225 gtk_container_add(GTK_CONTAINER(vbox), shelf_); |
224 | 226 |
225 GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); | 227 GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); |
226 gtk_alignment_set_padding( | 228 gtk_alignment_set_padding( |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 gtk_widget_queue_draw(frame_container_); | 383 gtk_widget_queue_draw(frame_container_); |
382 } else { | 384 } else { |
383 NOTREACHED(); | 385 NOTREACHED(); |
384 } | 386 } |
385 } | 387 } |
386 | 388 |
387 void BalloonViewImpl::OnCloseButton(GtkWidget* widget) { | 389 void BalloonViewImpl::OnCloseButton(GtkWidget* widget) { |
388 Close(true); | 390 Close(true); |
389 } | 391 } |
390 | 392 |
| 393 // We draw black dots on the bottom left and right corners to fill in the |
| 394 // border. Otherwise, the border has a gap because the sharp corners of the |
| 395 // HTML view cut off the roundedness of the notification window. |
| 396 gboolean BalloonViewImpl::OnContentsExpose(GtkWidget* sender, |
| 397 GdkEventExpose* event) { |
| 398 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(sender->window)); |
| 399 gdk_cairo_rectangle(cr, &event->area); |
| 400 cairo_clip(cr); |
| 401 |
| 402 // According to a discussion on a mailing list I found, these degenerate |
| 403 // paths are the officially supported way to draw points in Cairo. |
| 404 cairo_set_source_rgb(cr, 0, 0, 0); |
| 405 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); |
| 406 cairo_set_line_width(cr, 1.0); |
| 407 cairo_move_to(cr, 0.5, sender->allocation.height - 0.5); |
| 408 cairo_close_path(cr); |
| 409 cairo_move_to(cr, sender->allocation.width - 0.5, |
| 410 sender->allocation.height - 0.5); |
| 411 cairo_close_path(cr); |
| 412 cairo_stroke(cr); |
| 413 cairo_destroy(cr); |
| 414 |
| 415 return FALSE; |
| 416 } |
| 417 |
391 gboolean BalloonViewImpl::OnExpose(GtkWidget* sender, GdkEventExpose* event) { | 418 gboolean BalloonViewImpl::OnExpose(GtkWidget* sender, GdkEventExpose* event) { |
392 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(sender->window)); | 419 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(sender->window)); |
393 gdk_cairo_rectangle(cr, &event->area); | 420 gdk_cairo_rectangle(cr, &event->area); |
394 cairo_clip(cr); | 421 cairo_clip(cr); |
395 | 422 |
396 gfx::Size content_size = balloon_->content_size(); | 423 gfx::Size content_size = balloon_->content_size(); |
397 gfx::Point offset = GetContentsOffset(); | 424 gfx::Point offset = GetContentsOffset(); |
398 | 425 |
399 // Draw a background color behind the shelf. | 426 // Draw a background color behind the shelf. |
400 cairo_set_source_rgb(cr, kShelfBackgroundColorR, | 427 cairo_set_source_rgb(cr, kShelfBackgroundColorR, |
(...skipping 17 matching lines...) Expand all Loading... |
418 | 445 |
419 void BalloonViewImpl::OnOptionsMenuButton(GtkWidget* widget) { | 446 void BalloonViewImpl::OnOptionsMenuButton(GtkWidget* widget) { |
420 options_menu_->PopupAsContext(gtk_get_current_event_time()); | 447 options_menu_->PopupAsContext(gtk_get_current_event_time()); |
421 } | 448 } |
422 | 449 |
423 gboolean BalloonViewImpl::OnDestroy(GtkWidget* widget) { | 450 gboolean BalloonViewImpl::OnDestroy(GtkWidget* widget) { |
424 frame_container_ = NULL; | 451 frame_container_ = NULL; |
425 Close(false); | 452 Close(false); |
426 return FALSE; // Propagate. | 453 return FALSE; // Propagate. |
427 } | 454 } |
OLD | NEW |