Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.cc

Issue 8789016: Revert 112839 (it probably caused http://crbug.com/106299 ) - GTK: Port omnibox drawing from GdkG... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Deleted: svn:mergeinfo
OLDNEW
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/omnibox/omnibox_popup_view_gtk.h" 5 #include "chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.h"
6 6
7 #include <gtk/gtk.h> 7 #include <gtk/gtk.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <string> 10 #include <string>
(...skipping 16 matching lines...) Expand all
27 #include "chrome/browser/ui/omnibox/omnibox_view.h" 27 #include "chrome/browser/ui/omnibox/omnibox_view.h"
28 #include "chrome/common/chrome_notification_types.h" 28 #include "chrome/common/chrome_notification_types.h"
29 #include "content/public/browser/notification_source.h" 29 #include "content/public/browser/notification_source.h"
30 #include "grit/theme_resources.h" 30 #include "grit/theme_resources.h"
31 #include "ui/base/gtk/gtk_compat.h" 31 #include "ui/base/gtk/gtk_compat.h"
32 #include "ui/base/gtk/gtk_hig_constants.h" 32 #include "ui/base/gtk/gtk_hig_constants.h"
33 #include "ui/base/gtk/gtk_windowing.h" 33 #include "ui/base/gtk/gtk_windowing.h"
34 #include "ui/gfx/color_utils.h" 34 #include "ui/gfx/color_utils.h"
35 #include "ui/gfx/font.h" 35 #include "ui/gfx/font.h"
36 #include "ui/gfx/gtk_util.h" 36 #include "ui/gfx/gtk_util.h"
37 #include "ui/gfx/image/image.h"
38 #include "ui/gfx/image/cairo_cached_surface.h"
39 #include "ui/gfx/rect.h" 37 #include "ui/gfx/rect.h"
40 #include "ui/gfx/skia_utils_gtk.h" 38 #include "ui/gfx/skia_utils_gtk.h"
41 39
42 namespace { 40 namespace {
43 41
44 const GdkColor kBorderColor = GDK_COLOR_RGB(0xc7, 0xca, 0xce); 42 const GdkColor kBorderColor = GDK_COLOR_RGB(0xc7, 0xca, 0xce);
45 const GdkColor kBackgroundColor = GDK_COLOR_RGB(0xff, 0xff, 0xff); 43 const GdkColor kBackgroundColor = GDK_COLOR_RGB(0xff, 0xff, 0xff);
46 const GdkColor kSelectedBackgroundColor = GDK_COLOR_RGB(0xdf, 0xe6, 0xf6); 44 const GdkColor kSelectedBackgroundColor = GDK_COLOR_RGB(0xdf, 0xe6, 0xf6);
47 const GdkColor kHoveredBackgroundColor = GDK_COLOR_RGB(0xef, 0xf2, 0xfa); 45 const GdkColor kHoveredBackgroundColor = GDK_COLOR_RGB(0xef, 0xf2, 0xfa);
48 46
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 // Return a Rect for the space for a result line. This excludes the border, 97 // Return a Rect for the space for a result line. This excludes the border,
100 // but includes the padding. This is the area that is colored for a selection. 98 // but includes the padding. This is the area that is colored for a selection.
101 gfx::Rect GetRectForLine(size_t line, int width) { 99 gfx::Rect GetRectForLine(size_t line, int width) {
102 return gfx::Rect(kBorderThickness, 100 return gfx::Rect(kBorderThickness,
103 (line * kHeightPerResult) + kBorderThickness, 101 (line * kHeightPerResult) + kBorderThickness,
104 width - (kBorderThickness * 2), 102 width - (kBorderThickness * 2),
105 kHeightPerResult); 103 kHeightPerResult);
106 } 104 }
107 105
108 // Helper for drawing an entire pixbuf without dithering. 106 // Helper for drawing an entire pixbuf without dithering.
109 void DrawFullImage(cairo_t* cr, GtkWidget* widget, const gfx::Image* image, 107 void DrawFullPixbuf(GdkDrawable* drawable, GdkGC* gc, GdkPixbuf* pixbuf,
110 gint dest_x, gint dest_y) { 108 gint dest_x, gint dest_y) {
111 gfx::CairoCachedSurface* surface = image->ToCairo(); 109 gdk_draw_pixbuf(drawable, gc, pixbuf,
112 surface->SetSource(cr, widget, dest_x, dest_y); 110 0, 0, // Source.
113 cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); 111 dest_x, dest_y, // Dest.
114 cairo_rectangle(cr, dest_x, dest_y, surface->Width(), surface->Height()); 112 -1, -1, // Width/height (auto).
115 cairo_fill(cr); 113 GDK_RGB_DITHER_NONE, 0, 0); // Don't dither.
116 } 114 }
117 115
118 // TODO(deanm): Find some better home for this, and make it more efficient. 116 // TODO(deanm): Find some better home for this, and make it more efficient.
119 size_t GetUTF8Offset(const string16& text, size_t text_offset) { 117 size_t GetUTF8Offset(const string16& text, size_t text_offset) {
120 return UTF16ToUTF8(text.substr(0, text_offset)).length(); 118 return UTF16ToUTF8(text.substr(0, text_offset)).length();
121 } 119 }
122 120
123 // Generates the normal URL color, a green color used in unhighlighted URL 121 // Generates the normal URL color, a green color used in unhighlighted URL
124 // text. It is a mix of |kURLTextColor| and the current text color. Unlike the 122 // text. It is a mix of |kURLTextColor| and the current text color. Unlike the
125 // selected text color, it is more important to match the qualities of the 123 // selected text color, it is more important to match the qualities of the
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 } 331 }
334 332
335 OmniboxPopupViewGtk::~OmniboxPopupViewGtk() { 333 OmniboxPopupViewGtk::~OmniboxPopupViewGtk() {
336 // Explicitly destroy our model here, before we destroy our GTK widgets. 334 // Explicitly destroy our model here, before we destroy our GTK widgets.
337 // This is because the model destructor can call back into us, and we need 335 // This is because the model destructor can call back into us, and we need
338 // to make sure everything is still valid when it does. 336 // to make sure everything is still valid when it does.
339 model_.reset(); 337 model_.reset();
340 g_object_unref(layout_); 338 g_object_unref(layout_);
341 gtk_widget_destroy(window_); 339 gtk_widget_destroy(window_);
342 340
343 for (ImageMap::iterator it = images_.begin(); it != images_.end(); ++it) 341 for (PixbufMap::iterator it = pixbufs_.begin(); it != pixbufs_.end(); ++it)
344 delete it->second; 342 g_object_unref(it->second);
345 } 343 }
346 344
347 bool OmniboxPopupViewGtk::IsOpen() const { 345 bool OmniboxPopupViewGtk::IsOpen() const {
348 return opened_; 346 return opened_;
349 } 347 }
350 348
351 void OmniboxPopupViewGtk::InvalidateLine(size_t line) { 349 void OmniboxPopupViewGtk::InvalidateLine(size_t line) {
352 // TODO(deanm): Is it possible to use some constant for the width, instead 350 // TODO(deanm): Is it possible to use some constant for the width, instead
353 // of having to query the width of the window? 351 // of having to query the width of the window?
354 GdkRectangle line_rect = GetRectForLine( 352 GdkRectangle line_rect = GetRectForLine(
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 // OpenMatch() may close the popup, which will clear the result set and, by 476 // OpenMatch() may close the popup, which will clear the result set and, by
479 // extension, |match| and its contents. So copy the relevant match out to 477 // extension, |match| and its contents. So copy the relevant match out to
480 // make sure it stays alive until the call completes. 478 // make sure it stays alive until the call completes.
481 AutocompleteMatch match = model_->result().match_at(line); 479 AutocompleteMatch match = model_->result().match_at(line);
482 string16 keyword; 480 string16 keyword;
483 const bool is_keyword_hint = model_->GetKeywordForMatch(match, &keyword); 481 const bool is_keyword_hint = model_->GetKeywordForMatch(match, &keyword);
484 omnibox_view_->OpenMatch(match, disposition, GURL(), line, 482 omnibox_view_->OpenMatch(match, disposition, GURL(), line,
485 is_keyword_hint ? string16() : keyword); 483 is_keyword_hint ? string16() : keyword);
486 } 484 }
487 485
488 const gfx::Image* OmniboxPopupViewGtk::IconForMatch( 486 GdkPixbuf* OmniboxPopupViewGtk::IconForMatch(const AutocompleteMatch& match,
489 const AutocompleteMatch& match, bool selected) { 487 bool selected) {
490 const SkBitmap* bitmap = model_->GetIconIfExtensionMatch(match); 488 const SkBitmap* bitmap = model_->GetIconIfExtensionMatch(match);
491 if (bitmap) { 489 if (bitmap) {
492 if (!ContainsKey(images_, bitmap)) 490 if (!ContainsKey(pixbufs_, bitmap))
493 images_[bitmap] = new gfx::Image(bitmap); 491 pixbufs_[bitmap] = gfx::GdkPixbufFromSkBitmap(bitmap);
494 return images_[bitmap]; 492 return pixbufs_[bitmap];
495 } 493 }
496 494
497 int icon = match.starred ? 495 int icon = match.starred ?
498 IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match.type); 496 IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match.type);
499 if (selected) { 497 if (selected) {
500 switch (icon) { 498 switch (icon) {
501 case IDR_OMNIBOX_EXTENSION_APP: 499 case IDR_OMNIBOX_EXTENSION_APP:
502 icon = IDR_OMNIBOX_EXTENSION_APP_DARK; 500 icon = IDR_OMNIBOX_EXTENSION_APP_DARK;
503 break; 501 break;
504 case IDR_OMNIBOX_HTTP: 502 case IDR_OMNIBOX_HTTP:
505 icon = IDR_OMNIBOX_HTTP_DARK; 503 icon = IDR_OMNIBOX_HTTP_DARK;
506 break; 504 break;
507 case IDR_OMNIBOX_HISTORY: 505 case IDR_OMNIBOX_HISTORY:
508 icon = IDR_OMNIBOX_HISTORY_DARK; 506 icon = IDR_OMNIBOX_HISTORY_DARK;
509 break; 507 break;
510 case IDR_OMNIBOX_SEARCH: 508 case IDR_OMNIBOX_SEARCH:
511 icon = IDR_OMNIBOX_SEARCH_DARK; 509 icon = IDR_OMNIBOX_SEARCH_DARK;
512 break; 510 break;
513 case IDR_OMNIBOX_STAR: 511 case IDR_OMNIBOX_STAR:
514 icon = IDR_OMNIBOX_STAR_DARK; 512 icon = IDR_OMNIBOX_STAR_DARK;
515 break; 513 break;
516 default: 514 default:
517 NOTREACHED(); 515 NOTREACHED();
518 break; 516 break;
519 } 517 }
520 } 518 }
521 519
522 return theme_service_->GetImageNamed(icon); 520 // TODO(estade): Do we want to flip these for RTL? (Windows doesn't).
521 return theme_service_->GetPixbufNamed(icon);
523 } 522 }
524 523
525 gboolean OmniboxPopupViewGtk::HandleMotion(GtkWidget* widget, 524 gboolean OmniboxPopupViewGtk::HandleMotion(GtkWidget* widget,
526 GdkEventMotion* event) { 525 GdkEventMotion* event) {
527 // TODO(deanm): Windows has a bunch of complicated logic here. 526 // TODO(deanm): Windows has a bunch of complicated logic here.
528 size_t line = LineFromY(static_cast<int>(event->y)); 527 size_t line = LineFromY(static_cast<int>(event->y));
529 // There is both a hovered and selected line, hovered just means your mouse 528 // There is both a hovered and selected line, hovered just means your mouse
530 // is over it, but selected is what's showing in the location edit. 529 // is over it, but selected is what's showing in the location edit.
531 model_->SetHoveredLine(line); 530 model_->SetHoveredLine(line);
532 // Select the line if the user has the left mouse button down. 531 // Select the line if the user has the left mouse button down.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 gfx::Rect window_rect = GetWindowRect(event->window); 576 gfx::Rect window_rect = GetWindowRect(event->window);
578 gfx::Rect damage_rect = gfx::Rect(event->area); 577 gfx::Rect damage_rect = gfx::Rect(event->area);
579 // Handle when our window is super narrow. A bunch of the calculations 578 // Handle when our window is super narrow. A bunch of the calculations
580 // below would go negative, and really we're not going to fit anything 579 // below would go negative, and really we're not going to fit anything
581 // useful in such a small window anyway. Just don't paint anything. 580 // useful in such a small window anyway. Just don't paint anything.
582 // This means we won't draw the border, but, yeah, whatever. 581 // This means we won't draw the border, but, yeah, whatever.
583 // TODO(deanm): Make the code more robust and remove this check. 582 // TODO(deanm): Make the code more robust and remove this check.
584 if (window_rect.width() < (kIconAreaWidth * 3)) 583 if (window_rect.width() < (kIconAreaWidth * 3))
585 return TRUE; 584 return TRUE;
586 585
587 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); 586 GdkDrawable* drawable = GDK_DRAWABLE(event->window);
588 gdk_cairo_rectangle(cr, &event->area); 587 GdkGC* gc = gdk_gc_new(drawable);
589 cairo_clip(cr); 588
589 // kBorderColor is unallocated, so use the GdkRGB routine.
590 gdk_gc_set_rgb_fg_color(gc, &border_color_);
590 591
591 // This assert is kinda ugly, but it would be more currently unneeded work 592 // This assert is kinda ugly, but it would be more currently unneeded work
592 // to support painting a border that isn't 1 pixel thick. There is no point 593 // to support painting a border that isn't 1 pixel thick. There is no point
593 // in writing that code now, and explode if that day ever comes. 594 // in writing that code now, and explode if that day ever comes.
594 COMPILE_ASSERT(kBorderThickness == 1, border_1px_implied); 595 COMPILE_ASSERT(kBorderThickness == 1, border_1px_implied);
595 // Draw the 1px border around the entire window. 596 // Draw the 1px border around the entire window.
596 gdk_cairo_set_source_color(cr, &border_color_); 597 gdk_draw_rectangle(drawable, gc, FALSE,
597 cairo_rectangle(cr, 0, 0, window_rect.width(), window_rect.height()); 598 0, 0,
598 cairo_stroke(cr); 599 window_rect.width() - 1, window_rect.height() - 1);
599 600
600 pango_layout_set_height(layout_, kHeightPerResult * PANGO_SCALE); 601 pango_layout_set_height(layout_, kHeightPerResult * PANGO_SCALE);
601 602
602 for (size_t i = 0; i < result.size(); ++i) { 603 for (size_t i = 0; i < result.size(); ++i) {
603 gfx::Rect line_rect = GetRectForLine(i, window_rect.width()); 604 gfx::Rect line_rect = GetRectForLine(i, window_rect.width());
604 // Only repaint and layout damaged lines. 605 // Only repaint and layout damaged lines.
605 if (!line_rect.Intersects(damage_rect)) 606 if (!line_rect.Intersects(damage_rect))
606 continue; 607 continue;
607 608
608 const AutocompleteMatch& match = result.match_at(i); 609 const AutocompleteMatch& match = result.match_at(i);
609 bool is_selected = (model_->selected_line() == i); 610 bool is_selected = (model_->selected_line() == i);
610 bool is_hovered = (model_->hovered_line() == i); 611 bool is_hovered = (model_->hovered_line() == i);
611 if (is_selected || is_hovered) { 612 if (is_selected || is_hovered) {
612 gdk_cairo_set_source_color(cr, is_selected ? &selected_background_color_ : 613 gdk_gc_set_rgb_fg_color(gc, is_selected ? &selected_background_color_ :
613 &hovered_background_color_); 614 &hovered_background_color_);
614 // This entry is selected or hovered, fill a rect with the color. 615 // This entry is selected or hovered, fill a rect with the color.
615 cairo_rectangle(cr, line_rect.x(), line_rect.y(), 616 gdk_draw_rectangle(drawable, gc, TRUE,
616 line_rect.width(), line_rect.height()); 617 line_rect.x(), line_rect.y(),
617 cairo_fill(cr); 618 line_rect.width(), line_rect.height());
618 } 619 }
619 620
620 int icon_start_x = ltr ? kIconLeftPadding : 621 int icon_start_x = ltr ? kIconLeftPadding :
621 (line_rect.width() - kIconLeftPadding - kIconWidth); 622 (line_rect.width() - kIconLeftPadding - kIconWidth);
622 // Draw the icon for this result. 623 // Draw the icon for this result.
623 DrawFullImage(cr, widget, 624 DrawFullPixbuf(drawable, gc,
624 IconForMatch(match, is_selected), 625 IconForMatch(match, is_selected),
625 icon_start_x, line_rect.y() + kIconTopPadding); 626 icon_start_x, line_rect.y() + kIconTopPadding);
626 627
627 // Draw the results text vertically centered in the results space. 628 // Draw the results text vertically centered in the results space.
628 // First draw the contents / url, but don't let it take up the whole width 629 // First draw the contents / url, but don't let it take up the whole width
629 // if there is also a description to be shown. 630 // if there is also a description to be shown.
630 bool has_description = !match.description.empty(); 631 bool has_description = !match.description.empty();
631 int text_width = window_rect.width() - (kIconAreaWidth + kRightPadding); 632 int text_width = window_rect.width() - (kIconAreaWidth + kRightPadding);
632 int allocated_content_width = has_description ? 633 int allocated_content_width = has_description ?
633 static_cast<int>(text_width * kContentWidthPercentage) : text_width; 634 static_cast<int>(text_width * kContentWidthPercentage) : text_width;
634 pango_layout_set_width(layout_, allocated_content_width * PANGO_SCALE); 635 pango_layout_set_width(layout_, allocated_content_width * PANGO_SCALE);
635 636
(...skipping 11 matching lines...) Expand all
647 pango_layout_get_size(layout_, 648 pango_layout_get_size(layout_,
648 &actual_content_width, &actual_content_height); 649 &actual_content_width, &actual_content_height);
649 actual_content_width /= PANGO_SCALE; 650 actual_content_width /= PANGO_SCALE;
650 actual_content_height /= PANGO_SCALE; 651 actual_content_height /= PANGO_SCALE;
651 652
652 // DCHECK_LT(actual_content_height, kHeightPerResult); // Font is too tall. 653 // DCHECK_LT(actual_content_height, kHeightPerResult); // Font is too tall.
653 // Center the text within the line. 654 // Center the text within the line.
654 int content_y = std::max(line_rect.y(), 655 int content_y = std::max(line_rect.y(),
655 line_rect.y() + ((kHeightPerResult - actual_content_height) / 2)); 656 line_rect.y() + ((kHeightPerResult - actual_content_height) / 2));
656 657
657 cairo_save(cr); 658 gdk_draw_layout(drawable, gc,
658 cairo_move_to(cr, 659 ltr ? kIconAreaWidth :
659 ltr ? kIconAreaWidth :
660 (text_width - actual_content_width), 660 (text_width - actual_content_width),
661 content_y); 661 content_y, layout_);
662 pango_cairo_show_layout(cr, layout_);
663 cairo_restore(cr);
664 662
665 if (has_description) { 663 if (has_description) {
666 pango_layout_set_width(layout_, 664 pango_layout_set_width(layout_,
667 (text_width - actual_content_width) * PANGO_SCALE); 665 (text_width - actual_content_width) * PANGO_SCALE);
668 666
669 // In Windows, a boolean "force_dim" is passed as true for the 667 // In Windows, a boolean "force_dim" is passed as true for the
670 // description. Here, we pass the dim text color for both normal and dim, 668 // description. Here, we pass the dim text color for both normal and dim,
671 // to accomplish the same thing. 669 // to accomplish the same thing.
672 SetupLayoutForMatch(layout_, match.description, match.description_class, 670 SetupLayoutForMatch(layout_, match.description, match.description_class,
673 is_selected ? &selected_content_dim_text_color_ : 671 is_selected ? &selected_content_dim_text_color_ :
674 &content_dim_text_color_, 672 &content_dim_text_color_,
675 is_selected ? &selected_content_dim_text_color_ : 673 is_selected ? &selected_content_dim_text_color_ :
676 &content_dim_text_color_, 674 &content_dim_text_color_,
677 is_selected ? &url_selected_text_color_ : 675 is_selected ? &url_selected_text_color_ :
678 &url_text_color_, 676 &url_text_color_,
679 std::string(" - ")); 677 std::string(" - "));
680 gint actual_description_width; 678 gint actual_description_width;
681 pango_layout_get_size(layout_, &actual_description_width, NULL); 679 pango_layout_get_size(layout_, &actual_description_width, NULL);
682 680 gdk_draw_layout(drawable, gc, ltr ?
683 cairo_save(cr); 681 (kIconAreaWidth + actual_content_width) :
684 cairo_move_to(cr, ltr ? 682 (text_width - actual_content_width -
685 (kIconAreaWidth + actual_content_width) : 683 (actual_description_width / PANGO_SCALE)),
686 (text_width - actual_content_width - 684 content_y, layout_);
687 (actual_description_width / PANGO_SCALE)),
688 content_y);
689 pango_cairo_show_layout(cr, layout_);
690 cairo_restore(cr);
691 } 685 }
692 } 686 }
693 687
694 cairo_destroy(cr); 688 g_object_unref(gc);
689
695 return TRUE; 690 return TRUE;
696 } 691 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/gtk/omnibox/omnibox_popup_view_gtk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698