Chromium Code Reviews| 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/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 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 481 WindowOpenDisposition disposition) { | 481 WindowOpenDisposition disposition) { | 
| 482 // OpenMatch() may close the popup, which will clear the result set and, by | 482 // OpenMatch() may close the popup, which will clear the result set and, by | 
| 483 // extension, |match| and its contents. So copy the relevant match out to | 483 // extension, |match| and its contents. So copy the relevant match out to | 
| 484 // make sure it stays alive until the call completes. | 484 // make sure it stays alive until the call completes. | 
| 485 AutocompleteMatch match = model_->result().match_at(line); | 485 AutocompleteMatch match = model_->result().match_at(line); | 
| 486 omnibox_view_->OpenMatch(match, disposition, GURL(), line, | 486 omnibox_view_->OpenMatch(match, disposition, GURL(), line, | 
| 487 match.keyword); | 487 match.keyword); | 
| 488 } | 488 } | 
| 489 | 489 | 
| 490 const gfx::Image* OmniboxPopupViewGtk::IconForMatch( | 490 const gfx::Image* OmniboxPopupViewGtk::IconForMatch( | 
| 491 const AutocompleteMatch& match, bool selected) { | 491 const AutocompleteMatch& match, bool selected, bool is_selected_keyword) { | 
| 
 
Peter Kasting
2012/03/01 22:02:12
Nit: One arg per line
 
 | |
| 492 const SkBitmap* bitmap = model_->GetIconIfExtensionMatch(match); | 492 const SkBitmap* bitmap = model_->GetIconIfExtensionMatch(match); | 
| 493 if (bitmap) { | 493 if (bitmap) { | 
| 494 if (!ContainsKey(images_, bitmap)) { | 494 if (!ContainsKey(images_, bitmap)) { | 
| 495 // gfx::Image wants ownership of bitmaps given to it, and we might as | 495 // gfx::Image wants ownership of bitmaps given to it, and we might as | 
| 496 // well make the bitmap copy a format that will be used. | 496 // well make the bitmap copy a format that will be used. | 
| 497 images_[bitmap] = new gfx::Image(gfx::GdkPixbufFromSkBitmap(bitmap)); | 497 images_[bitmap] = new gfx::Image(gfx::GdkPixbufFromSkBitmap(bitmap)); | 
| 498 } | 498 } | 
| 499 return images_[bitmap]; | 499 return images_[bitmap]; | 
| 500 } | 500 } | 
| 501 | 501 | 
| 502 int icon = match.starred ? | 502 int icon; | 
| 503 IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match.type); | 503 if (is_selected_keyword) | 
| 504 icon = IDR_OMNIBOX_TTS; | |
| 505 else if (match.starred) | |
| 506 icon = IDR_OMNIBOX_STAR; | |
| 507 else | |
| 508 icon = AutocompleteMatch::TypeToIcon(match.type); | |
| 509 | |
| 504 if (selected) { | 510 if (selected) { | 
| 505 switch (icon) { | 511 switch (icon) { | 
| 506 case IDR_OMNIBOX_EXTENSION_APP: | 512 case IDR_OMNIBOX_EXTENSION_APP: | 
| 507 icon = IDR_OMNIBOX_EXTENSION_APP_DARK; | 513 icon = IDR_OMNIBOX_EXTENSION_APP_DARK; | 
| 508 break; | 514 break; | 
| 509 case IDR_OMNIBOX_HTTP: | 515 case IDR_OMNIBOX_HTTP: | 
| 510 icon = IDR_OMNIBOX_HTTP_DARK; | 516 icon = IDR_OMNIBOX_HTTP_DARK; | 
| 511 break; | 517 break; | 
| 512 case IDR_OMNIBOX_HISTORY: | 518 case IDR_OMNIBOX_HISTORY: | 
| 513 icon = IDR_OMNIBOX_HISTORY_DARK; | 519 icon = IDR_OMNIBOX_HISTORY_DARK; | 
| 514 break; | 520 break; | 
| 515 case IDR_OMNIBOX_SEARCH: | 521 case IDR_OMNIBOX_SEARCH: | 
| 516 icon = IDR_OMNIBOX_SEARCH_DARK; | 522 icon = IDR_OMNIBOX_SEARCH_DARK; | 
| 517 break; | 523 break; | 
| 518 case IDR_OMNIBOX_STAR: | 524 case IDR_OMNIBOX_STAR: | 
| 519 icon = IDR_OMNIBOX_STAR_DARK; | 525 icon = IDR_OMNIBOX_STAR_DARK; | 
| 520 break; | 526 break; | 
| 527 case IDR_OMNIBOX_TTS: | |
| 528 icon = IDR_OMNIBOX_TTS_DARK; | |
| 529 break; | |
| 521 default: | 530 default: | 
| 522 NOTREACHED(); | 531 NOTREACHED(); | 
| 523 break; | 532 break; | 
| 524 } | 533 } | 
| 525 } | 534 } | 
| 526 | 535 | 
| 527 return theme_service_->GetImageNamed(icon); | 536 return theme_service_->GetImageNamed(icon); | 
| 528 } | 537 } | 
| 529 | 538 | 
| 539 void OmniboxPopupViewGtk::GetForMatch(size_t index, | |
| 540 const AutocompleteMatch** match, | |
| 541 bool* is_selected_keyword) { | |
| 542 const AutocompleteResult& result = model_->result(); | |
| 543 | |
| 544 if (result.match_at(index).associated_keyword.get() && | |
| 545 model_->selected_line() == index && | |
| 546 model_->selected_line_state() == AutocompletePopupModel::KEYWORD) { | |
| 547 *match = result.match_at(index).associated_keyword.get(); | |
| 548 *is_selected_keyword = true; | |
| 549 return; | |
| 550 } | |
| 551 | |
| 552 *match = &result.match_at(index); | |
| 553 *is_selected_keyword = false; | |
| 554 } | |
| 555 | |
| 530 gboolean OmniboxPopupViewGtk::HandleMotion(GtkWidget* widget, | 556 gboolean OmniboxPopupViewGtk::HandleMotion(GtkWidget* widget, | 
| 531 GdkEventMotion* event) { | 557 GdkEventMotion* event) { | 
| 532 // TODO(deanm): Windows has a bunch of complicated logic here. | 558 // TODO(deanm): Windows has a bunch of complicated logic here. | 
| 533 size_t line = LineFromY(static_cast<int>(event->y)); | 559 size_t line = LineFromY(static_cast<int>(event->y)); | 
| 534 // There is both a hovered and selected line, hovered just means your mouse | 560 // There is both a hovered and selected line, hovered just means your mouse | 
| 535 // is over it, but selected is what's showing in the location edit. | 561 // is over it, but selected is what's showing in the location edit. | 
| 536 model_->SetHoveredLine(line); | 562 model_->SetHoveredLine(line); | 
| 537 // Select the line if the user has the left mouse button down. | 563 // Select the line if the user has the left mouse button down. | 
| 538 if (!ignore_mouse_drag_ && (event->state & GDK_BUTTON1_MASK)) | 564 if (!ignore_mouse_drag_ && (event->state & GDK_BUTTON1_MASK)) | 
| 539 model_->SetSelectedLine(line, false, false); | 565 model_->SetSelectedLine(line, false, false); | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 603 cairo_stroke(cr); | 629 cairo_stroke(cr); | 
| 604 | 630 | 
| 605 pango_layout_set_height(layout_, kHeightPerResult * PANGO_SCALE); | 631 pango_layout_set_height(layout_, kHeightPerResult * PANGO_SCALE); | 
| 606 | 632 | 
| 607 for (size_t i = 0; i < result.size(); ++i) { | 633 for (size_t i = 0; i < result.size(); ++i) { | 
| 608 gfx::Rect line_rect = GetRectForLine(i, window_rect.width()); | 634 gfx::Rect line_rect = GetRectForLine(i, window_rect.width()); | 
| 609 // Only repaint and layout damaged lines. | 635 // Only repaint and layout damaged lines. | 
| 610 if (!line_rect.Intersects(damage_rect)) | 636 if (!line_rect.Intersects(damage_rect)) | 
| 611 continue; | 637 continue; | 
| 612 | 638 | 
| 613 const AutocompleteMatch& match = result.match_at(i); | 639 const AutocompleteMatch* match = NULL; | 
| 640 bool is_selected_keyword = false; | |
| 641 GetForMatch(i, &match, &is_selected_keyword); | |
| 614 bool is_selected = (model_->selected_line() == i); | 642 bool is_selected = (model_->selected_line() == i); | 
| 615 bool is_hovered = (model_->hovered_line() == i); | 643 bool is_hovered = (model_->hovered_line() == i); | 
| 616 if (is_selected || is_hovered) { | 644 if (is_selected || is_hovered) { | 
| 617 gdk_cairo_set_source_color(cr, is_selected ? &selected_background_color_ : | 645 gdk_cairo_set_source_color(cr, is_selected ? &selected_background_color_ : | 
| 618 &hovered_background_color_); | 646 &hovered_background_color_); | 
| 619 // This entry is selected or hovered, fill a rect with the color. | 647 // This entry is selected or hovered, fill a rect with the color. | 
| 620 cairo_rectangle(cr, line_rect.x(), line_rect.y(), | 648 cairo_rectangle(cr, line_rect.x(), line_rect.y(), | 
| 621 line_rect.width(), line_rect.height()); | 649 line_rect.width(), line_rect.height()); | 
| 622 cairo_fill(cr); | 650 cairo_fill(cr); | 
| 623 } | 651 } | 
| 624 | 652 | 
| 625 int icon_start_x = ltr ? kIconLeftPadding : | 653 int icon_start_x = ltr ? kIconLeftPadding : | 
| 626 (line_rect.width() - kIconLeftPadding - kIconWidth); | 654 (line_rect.width() - kIconLeftPadding - kIconWidth); | 
| 627 // Draw the icon for this result. | 655 // Draw the icon for this result. | 
| 628 DrawFullImage(cr, widget, | 656 DrawFullImage(cr, widget, | 
| 629 IconForMatch(match, is_selected), | 657 IconForMatch(*match, is_selected, is_selected_keyword), | 
| 630 icon_start_x, line_rect.y() + kIconTopPadding); | 658 icon_start_x, line_rect.y() + kIconTopPadding); | 
| 631 | 659 | 
| 632 // Draw the results text vertically centered in the results space. | 660 // Draw the results text vertically centered in the results space. | 
| 633 // First draw the contents / url, but don't let it take up the whole width | 661 // First draw the contents / url, but don't let it take up the whole width | 
| 634 // if there is also a description to be shown. | 662 // if there is also a description to be shown. | 
| 635 bool has_description = !match.description.empty(); | 663 bool has_description = !match->description.empty(); | 
| 636 int text_width = window_rect.width() - (kIconAreaWidth + kRightPadding); | 664 int text_width = window_rect.width() - (kIconAreaWidth + kRightPadding); | 
| 637 int allocated_content_width = has_description ? | 665 int allocated_content_width = has_description ? | 
| 638 static_cast<int>(text_width * kContentWidthPercentage) : text_width; | 666 static_cast<int>(text_width * kContentWidthPercentage) : text_width; | 
| 639 pango_layout_set_width(layout_, allocated_content_width * PANGO_SCALE); | 667 pango_layout_set_width(layout_, allocated_content_width * PANGO_SCALE); | 
| 640 | 668 | 
| 641 // Note: We force to URL to LTR for all text directions. | 669 // Note: We force to URL to LTR for all text directions. | 
| 642 SetupLayoutForMatch(layout_, match.contents, match.contents_class, | 670 SetupLayoutForMatch(layout_, match->contents, match->contents_class, | 
| 643 is_selected ? &selected_content_text_color_ : | 671 is_selected ? &selected_content_text_color_ : | 
| 644 &content_text_color_, | 672 &content_text_color_, | 
| 645 is_selected ? &selected_content_dim_text_color_ : | 673 is_selected ? &selected_content_dim_text_color_ : | 
| 646 &content_dim_text_color_, | 674 &content_dim_text_color_, | 
| 647 is_selected ? &url_selected_text_color_ : | 675 is_selected ? &url_selected_text_color_ : | 
| 648 &url_text_color_, | 676 &url_text_color_, | 
| 649 std::string()); | 677 std::string()); | 
| 650 | 678 | 
| 651 int actual_content_width, actual_content_height; | 679 int actual_content_width, actual_content_height; | 
| 652 pango_layout_get_size(layout_, | 680 pango_layout_get_size(layout_, | 
| (...skipping 14 matching lines...) Expand all Loading... | |
| 667 pango_cairo_show_layout(cr, layout_); | 695 pango_cairo_show_layout(cr, layout_); | 
| 668 cairo_restore(cr); | 696 cairo_restore(cr); | 
| 669 | 697 | 
| 670 if (has_description) { | 698 if (has_description) { | 
| 671 pango_layout_set_width(layout_, | 699 pango_layout_set_width(layout_, | 
| 672 (text_width - actual_content_width) * PANGO_SCALE); | 700 (text_width - actual_content_width) * PANGO_SCALE); | 
| 673 | 701 | 
| 674 // In Windows, a boolean "force_dim" is passed as true for the | 702 // In Windows, a boolean "force_dim" is passed as true for the | 
| 675 // description. Here, we pass the dim text color for both normal and dim, | 703 // description. Here, we pass the dim text color for both normal and dim, | 
| 676 // to accomplish the same thing. | 704 // to accomplish the same thing. | 
| 677 SetupLayoutForMatch(layout_, match.description, match.description_class, | 705 SetupLayoutForMatch(layout_, match->description, match->description_class, | 
| 678 is_selected ? &selected_content_dim_text_color_ : | 706 is_selected ? &selected_content_dim_text_color_ : | 
| 679 &content_dim_text_color_, | 707 &content_dim_text_color_, | 
| 680 is_selected ? &selected_content_dim_text_color_ : | 708 is_selected ? &selected_content_dim_text_color_ : | 
| 681 &content_dim_text_color_, | 709 &content_dim_text_color_, | 
| 682 is_selected ? &url_selected_text_color_ : | 710 is_selected ? &url_selected_text_color_ : | 
| 683 &url_text_color_, | 711 &url_text_color_, | 
| 684 std::string(" - ")); | 712 std::string(" - ")); | 
| 685 gint actual_description_width; | 713 gint actual_description_width; | 
| 686 pango_layout_get_size(layout_, &actual_description_width, NULL); | 714 pango_layout_get_size(layout_, &actual_description_width, NULL); | 
| 687 | 715 | 
| 688 cairo_save(cr); | 716 cairo_save(cr); | 
| 689 cairo_move_to(cr, ltr ? | 717 cairo_move_to(cr, ltr ? | 
| 690 (kIconAreaWidth + actual_content_width) : | 718 (kIconAreaWidth + actual_content_width) : | 
| 691 (text_width - actual_content_width - | 719 (text_width - actual_content_width - | 
| 692 (actual_description_width / PANGO_SCALE)), | 720 (actual_description_width / PANGO_SCALE)), | 
| 693 content_y); | 721 content_y); | 
| 694 pango_cairo_show_layout(cr, layout_); | 722 pango_cairo_show_layout(cr, layout_); | 
| 695 cairo_restore(cr); | 723 cairo_restore(cr); | 
| 696 } | 724 } | 
| 725 | |
| 726 if (match->associated_keyword.get()) { | |
| 727 // If this entry has an associated keyword, draw the arrow at the extreme | |
| 728 // other side of the omnibox. | |
| 729 icon_start_x = ltr ? (line_rect.width() - kIconLeftPadding - kIconWidth) : | |
| 730 kIconLeftPadding; | |
| 
 
Peter Kasting
2012/03/01 22:02:12
Nit: Indent 4
 
 | |
| 731 // Draw the icon for this result. | |
| 732 DrawFullImage(cr, widget, | |
| 733 theme_service_->GetImageNamed( | |
| 734 is_selected ? IDR_OMNIBOX_TTS_DARK : IDR_OMNIBOX_TTS), | |
| 735 icon_start_x, line_rect.y() + kIconTopPadding); | |
| 736 } | |
| 697 } | 737 } | 
| 698 | 738 | 
| 699 cairo_destroy(cr); | 739 cairo_destroy(cr); | 
| 700 return TRUE; | 740 return TRUE; | 
| 701 } | 741 } | 
| OLD | NEW |