| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this |
| 2 // source code is governed by a BSD-style license that can be found in the | 2 // source code is governed by a BSD-style license that can be found in the |
| 3 // LICENSE file. | 3 // LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h" | 5 #include "chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h" |
| 6 | 6 |
| 7 #include <objidl.h> | |
| 8 #include <commctrl.h> | |
| 9 #include <dwmapi.h> | |
| 10 | |
| 11 #include "app/gfx/canvas.h" | 7 #include "app/gfx/canvas.h" |
| 12 #include "app/gfx/color_utils.h" | 8 #include "app/gfx/color_utils.h" |
| 13 #include "app/gfx/insets.h" | 9 #include "app/gfx/insets.h" |
| 14 #include "app/gfx/path.h" | 10 #include "app/gfx/path.h" |
| 15 #include "app/l10n_util.h" | 11 #include "app/l10n_util.h" |
| 16 #include "app/resource_bundle.h" | 12 #include "app/resource_bundle.h" |
| 17 #include "app/theme_provider.h" | 13 #include "app/theme_provider.h" |
| 18 #include "app/win_util.h" | |
| 19 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.h" |
| 20 #include "chrome/browser/autocomplete/autocomplete_edit_view_win.h" | 15 #include "chrome/browser/autocomplete/autocomplete_edit_view.h" |
| 21 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" | 16 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" |
| 22 #include "chrome/browser/views/autocomplete/autocomplete_popup_win.h" | |
| 23 #include "grit/generated_resources.h" | 17 #include "grit/generated_resources.h" |
| 24 #include "grit/theme_resources.h" | 18 #include "grit/theme_resources.h" |
| 25 #include "third_party/skia/include/core/SkShader.h" | 19 #include "third_party/skia/include/core/SkShader.h" |
| 26 #include "third_party/icu38/public/common/unicode/ubidi.h" | 20 #include "third_party/icu38/public/common/unicode/ubidi.h" |
| 27 #include "views/widget/widget.h" | 21 #include "views/widget/widget.h" |
| 28 | 22 |
| 23 #if defined(OS_WIN) |
| 24 #include <objidl.h> |
| 25 #include <commctrl.h> |
| 26 #include <dwmapi.h> |
| 27 |
| 28 #include "app/win_util.h" |
| 29 #include "chrome/browser/views/autocomplete/autocomplete_popup_win.h" |
| 30 #else |
| 31 #include "chrome/browser/views/autocomplete/autocomplete_popup_gtk.h" |
| 32 #endif |
| 33 |
| 29 // Colors for various components of the view. | 34 // Colors for various components of the view. |
| 35 #if defined(OS_WIN) |
| 30 static const SkColor kBackgroundColor = | 36 static const SkColor kBackgroundColor = |
| 31 color_utils::GetSysSkColor(COLOR_WINDOW); | 37 color_utils::GetSysSkColor(COLOR_WINDOW); |
| 32 static const SkColor kSelectedBackgroundColor = | 38 static const SkColor kSelectedBackgroundColor = |
| 33 color_utils::GetSysSkColor(COLOR_HIGHLIGHT); | 39 color_utils::GetSysSkColor(COLOR_HIGHLIGHT); |
| 34 static const SkColor kHoverBackgroundColor = | 40 static const SkColor kHoverBackgroundColor = |
| 35 SkColorSetA(kSelectedBackgroundColor, 127); | 41 SkColorSetA(kSelectedBackgroundColor, 127); |
| 36 static const SkColor kTextColor = | 42 static const SkColor kTextColor = |
| 37 color_utils::GetSysSkColor(COLOR_WINDOWTEXT); | 43 color_utils::GetSysSkColor(COLOR_WINDOWTEXT); |
| 38 static const SkColor kSelectedTextColor = | 44 static const SkColor kSelectedTextColor = |
| 39 color_utils::GetSysSkColor(COLOR_HIGHLIGHTTEXT); | 45 color_utils::GetSysSkColor(COLOR_HIGHLIGHTTEXT); |
| 40 static const SkColor kDimTextColor = | 46 static const SkColor kDimTextColor = |
| 41 color_utils::GetSysSkColor(COLOR_GRAYTEXT); | 47 color_utils::GetSysSkColor(COLOR_GRAYTEXT); |
| 42 static const SkColor kSelectedDimTextColor = | 48 static const SkColor kSelectedDimTextColor = |
| 43 color_utils::GetSysSkColor(COLOR_HIGHLIGHTTEXT); | 49 color_utils::GetSysSkColor(COLOR_HIGHLIGHTTEXT); |
| 50 #else |
| 51 // TODO(beng): source from theme provider. |
| 52 static const SkColor kBackgroundColor = SK_ColorWHITE; |
| 53 static const SkColor kSelectedBackgroundColor = SK_ColorBLUE; |
| 54 static const SkColor kHoverBackgroundColor = SK_ColorCYAN; |
| 55 static const SkColor kTextColor = SK_ColorBLACK; |
| 56 static const SkColor kSelectedTextColor = SK_ColorWHITE; |
| 57 static const SkColor kDimTextColor = SK_ColorGRAY; |
| 58 static const SkColor kSelectedDimTextColor = SK_ColorWHITE; |
| 59 #endif |
| 44 static const SkColor kStandardURLColor = SkColorSetRGB(0, 0x80, 0); | 60 static const SkColor kStandardURLColor = SkColorSetRGB(0, 0x80, 0); |
| 45 static const SkColor kHighlightURLColor = SkColorSetRGB(0xD0, 0xFF, 0xD0); | 61 static const SkColor kHighlightURLColor = SkColorSetRGB(0xD0, 0xFF, 0xD0); |
| 46 static const int kGlassPopupTransparency = 240; | 62 static const int kGlassPopupTransparency = 240; |
| 47 static const int kOpaquePopupTransparency = 255; | 63 static const int kOpaquePopupTransparency = 255; |
| 48 static const int kHoverRowAlpha = 0x40; | 64 static const int kHoverRowAlpha = 0x40; |
| 49 // The minimum distance between the top and bottom of the icon and the top or | 65 // The minimum distance between the top and bottom of the icon and the top or |
| 50 // bottom of the row. "Minimum" is used because the vertical padding may be | 66 // bottom of the row. "Minimum" is used because the vertical padding may be |
| 51 // larger, depending on the size of the text. | 67 // larger, depending on the size of the text. |
| 52 static const int kIconVerticalPadding = 2; | 68 static const int kIconVerticalPadding = 2; |
| 53 // The minimum distance between the top and bottom of the text and the top or | 69 // The minimum distance between the top and bottom of the text and the top or |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 dropshadow_bottomleft_ = rb.GetBitmapNamed(IDR_OMNIBOX_POPUP_DS_BL); | 666 dropshadow_bottomleft_ = rb.GetBitmapNamed(IDR_OMNIBOX_POPUP_DS_BL); |
| 651 initialized = true; | 667 initialized = true; |
| 652 } | 668 } |
| 653 } | 669 } |
| 654 | 670 |
| 655 //////////////////////////////////////////////////////////////////////////////// | 671 //////////////////////////////////////////////////////////////////////////////// |
| 656 // AutocompletePopupContentsView, public: | 672 // AutocompletePopupContentsView, public: |
| 657 | 673 |
| 658 AutocompletePopupContentsView::AutocompletePopupContentsView( | 674 AutocompletePopupContentsView::AutocompletePopupContentsView( |
| 659 const gfx::Font& font, | 675 const gfx::Font& font, |
| 660 AutocompleteEditViewWin* edit_view, | 676 AutocompleteEditView* edit_view, |
| 661 AutocompleteEditModel* edit_model, | 677 AutocompleteEditModel* edit_model, |
| 662 Profile* profile, | 678 Profile* profile, |
| 663 AutocompletePopupPositioner* popup_positioner) | 679 AutocompletePopupPositioner* popup_positioner) |
| 680 #if defined(OS_WIN) |
| 664 : popup_(new AutocompletePopupWin(this)), | 681 : popup_(new AutocompletePopupWin(this)), |
| 682 #else |
| 683 : popup_(new AutocompletePopupGtk(this)), |
| 684 #endif |
| 665 model_(new AutocompletePopupModel(this, edit_model, profile)), | 685 model_(new AutocompletePopupModel(this, edit_model, profile)), |
| 666 edit_view_(edit_view), | 686 edit_view_(edit_view), |
| 667 popup_positioner_(popup_positioner), | 687 popup_positioner_(popup_positioner), |
| 668 result_font_(font.DeriveFont(kEditFontAdjust)), | 688 result_font_(font.DeriveFont(kEditFontAdjust)), |
| 669 ALLOW_THIS_IN_INITIALIZER_LIST(size_animation_(this)) { | 689 ALLOW_THIS_IN_INITIALIZER_LIST(size_animation_(this)) { |
| 670 set_border(new PopupBorder); | 690 set_border(new PopupBorder); |
| 671 } | 691 } |
| 672 | 692 |
| 673 gfx::Rect AutocompletePopupContentsView::GetPopupBounds() const { | 693 gfx::Rect AutocompletePopupContentsView::GetPopupBounds() const { |
| 674 if (!size_animation_.IsAnimating()) | 694 if (!size_animation_.IsAnimating()) |
| 675 return target_bounds_; | 695 return target_bounds_; |
| 676 | 696 |
| 677 gfx::Rect current_frame_bounds = start_bounds_; | 697 gfx::Rect current_frame_bounds = start_bounds_; |
| 678 int total_height_delta = target_bounds_.height() - start_bounds_.height(); | 698 int total_height_delta = target_bounds_.height() - start_bounds_.height(); |
| 679 // Round |current_height_delta| instead of truncating so we won't leave single | 699 // Round |current_height_delta| instead of truncating so we won't leave single |
| 680 // white pixels at the bottom of the popup as long when animating very small | 700 // white pixels at the bottom of the popup as long when animating very small |
| 681 // height differences. | 701 // height differences. |
| 682 int current_height_delta = static_cast<int>( | 702 int current_height_delta = static_cast<int>( |
| 683 size_animation_.GetCurrentValue() * total_height_delta - 0.5); | 703 size_animation_.GetCurrentValue() * total_height_delta - 0.5); |
| 684 current_frame_bounds.set_height( | 704 current_frame_bounds.set_height( |
| 685 current_frame_bounds.height() + current_height_delta); | 705 current_frame_bounds.height() + current_height_delta); |
| 686 return current_frame_bounds; | 706 return current_frame_bounds; |
| 687 } | 707 } |
| 688 | 708 |
| 689 //////////////////////////////////////////////////////////////////////////////// | 709 //////////////////////////////////////////////////////////////////////////////// |
| 690 // AutocompletePopupContentsView, AutocompletePopupView overrides: | 710 // AutocompletePopupContentsView, AutocompletePopupView overrides: |
| 691 | 711 |
| 692 bool AutocompletePopupContentsView::IsOpen() const { | 712 bool AutocompletePopupContentsView::IsOpen() const { |
| 693 return popup_->IsWindow() && popup_->IsVisible(); | 713 return popup_->IsOpen(); |
| 694 } | 714 } |
| 695 | 715 |
| 696 void AutocompletePopupContentsView::InvalidateLine(size_t line) { | 716 void AutocompletePopupContentsView::InvalidateLine(size_t line) { |
| 697 GetChildViewAt(static_cast<int>(line))->SchedulePaint(); | 717 GetChildViewAt(static_cast<int>(line))->SchedulePaint(); |
| 698 } | 718 } |
| 699 | 719 |
| 700 void AutocompletePopupContentsView::UpdatePopupAppearance() { | 720 void AutocompletePopupContentsView::UpdatePopupAppearance() { |
| 701 if (model_->result().empty()) { | 721 if (model_->result().empty()) { |
| 702 // No matches, close any existing popup. | 722 // No matches, close any existing popup. |
| 703 if (popup_->IsWindow()) { | 723 if (popup_->IsCreated()) { |
| 704 size_animation_.Stop(); | 724 size_animation_.Stop(); |
| 705 popup_->Hide(); | 725 popup_->Hide(); |
| 706 } | 726 } |
| 707 return; | 727 return; |
| 708 } | 728 } |
| 709 | 729 |
| 710 // Update the match cached by each row, in the process of doing so make sure | 730 // Update the match cached by each row, in the process of doing so make sure |
| 711 // we have enough row views. | 731 // we have enough row views. |
| 712 int total_child_height = 0; | 732 int total_child_height = 0; |
| 713 size_t child_view_count = GetChildViewCount(); | 733 size_t child_view_count = GetChildViewCount(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 732 -insets.bottom()); | 752 -insets.bottom()); |
| 733 | 753 |
| 734 // If we're animating and our target height changes, reset the animation. | 754 // If we're animating and our target height changes, reset the animation. |
| 735 // NOTE: If we just reset blindly on _every_ update, then when the user types | 755 // NOTE: If we just reset blindly on _every_ update, then when the user types |
| 736 // rapidly we could get "stuck" trying repeatedly to animate shrinking by the | 756 // rapidly we could get "stuck" trying repeatedly to animate shrinking by the |
| 737 // last few pixels to get to one visible result. | 757 // last few pixels to get to one visible result. |
| 738 if (new_target_bounds.height() != target_bounds_.height()) | 758 if (new_target_bounds.height() != target_bounds_.height()) |
| 739 size_animation_.Reset(); | 759 size_animation_.Reset(); |
| 740 target_bounds_ = new_target_bounds; | 760 target_bounds_ = new_target_bounds; |
| 741 | 761 |
| 742 if (!popup_->IsWindow()) { | 762 if (!popup_->IsCreated()) { |
| 743 // If we've never been shown, we need to create the window. | 763 // If we've never been shown, we need to create the window. |
| 744 popup_->Init(edit_view_, this); | 764 popup_->Init(edit_view_, this); |
| 745 } else { | 765 } else { |
| 746 // Animate the popup shrinking, but don't animate growing larger (or | 766 // Animate the popup shrinking, but don't animate growing larger (or |
| 747 // appearing for the first time) since that would make the popup feel less | 767 // appearing for the first time) since that would make the popup feel less |
| 748 // responsive. | 768 // responsive. |
| 749 GetWidget()->GetBounds(&start_bounds_, true); | 769 GetWidget()->GetBounds(&start_bounds_, true); |
| 750 if (popup_->IsVisible() && | 770 if (popup_->IsVisible() && |
| 751 (target_bounds_.height() < start_bounds_.height())) | 771 (target_bounds_.height() < start_bounds_.height())) |
| 752 size_animation_.Show(); | 772 size_animation_.Show(); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 rect.set(SkIntToScalar(bounding_rect.x()), | 910 rect.set(SkIntToScalar(bounding_rect.x()), |
| 891 SkIntToScalar(bounding_rect.y()), | 911 SkIntToScalar(bounding_rect.y()), |
| 892 SkIntToScalar(bounding_rect.right()), | 912 SkIntToScalar(bounding_rect.right()), |
| 893 SkIntToScalar(bounding_rect.bottom())); | 913 SkIntToScalar(bounding_rect.bottom())); |
| 894 | 914 |
| 895 SkScalar radius = SkIntToScalar(PopupBorder::GetBorderRadius()); | 915 SkScalar radius = SkIntToScalar(PopupBorder::GetBorderRadius()); |
| 896 path->addRoundRect(rect, radius, radius); | 916 path->addRoundRect(rect, radius, radius); |
| 897 } | 917 } |
| 898 | 918 |
| 899 void AutocompletePopupContentsView::UpdateBlurRegion() { | 919 void AutocompletePopupContentsView::UpdateBlurRegion() { |
| 920 #if defined(OS_WIN) |
| 900 // We only support background blurring on Vista with Aero-Glass enabled. | 921 // We only support background blurring on Vista with Aero-Glass enabled. |
| 901 if (!win_util::ShouldUseVistaFrame() || !GetWidget()) | 922 if (!win_util::ShouldUseVistaFrame() || !GetWidget()) |
| 902 return; | 923 return; |
| 903 | 924 |
| 904 // Provide a blurred background effect within the contents region of the | 925 // Provide a blurred background effect within the contents region of the |
| 905 // popup. | 926 // popup. |
| 906 DWM_BLURBEHIND bb = {0}; | 927 DWM_BLURBEHIND bb = {0}; |
| 907 bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; | 928 bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; |
| 908 bb.fEnable = true; | 929 bb.fEnable = true; |
| 909 | 930 |
| 910 // Translate the contents rect into widget coordinates, since that's what | 931 // Translate the contents rect into widget coordinates, since that's what |
| 911 // DwmEnableBlurBehindWindow expects a region in. | 932 // DwmEnableBlurBehindWindow expects a region in. |
| 912 gfx::Rect contents_rect = GetLocalBounds(false); | 933 gfx::Rect contents_rect = GetLocalBounds(false); |
| 913 gfx::Point origin(contents_rect.origin()); | 934 gfx::Point origin(contents_rect.origin()); |
| 914 views::View::ConvertPointToWidget(this, &origin); | 935 views::View::ConvertPointToWidget(this, &origin); |
| 915 contents_rect.set_origin(origin); | 936 contents_rect.set_origin(origin); |
| 916 | 937 |
| 917 gfx::Path contents_path; | 938 gfx::Path contents_path; |
| 918 MakeContentsPath(&contents_path, contents_rect); | 939 MakeContentsPath(&contents_path, contents_rect); |
| 919 ScopedGDIObject<HRGN> popup_region; | 940 ScopedGDIObject<HRGN> popup_region; |
| 920 popup_region.Set(contents_path.CreateHRGN()); | 941 popup_region.Set(contents_path.CreateHRGN()); |
| 921 bb.hRgnBlur = popup_region.Get(); | 942 bb.hRgnBlur = popup_region.Get(); |
| 922 DwmEnableBlurBehindWindow(GetWidget()->GetNativeView(), &bb); | 943 DwmEnableBlurBehindWindow(GetWidget()->GetNativeView(), &bb); |
| 944 #endif |
| 923 } | 945 } |
| 924 | 946 |
| 925 void AutocompletePopupContentsView::MakeCanvasTransparent( | 947 void AutocompletePopupContentsView::MakeCanvasTransparent( |
| 926 gfx::Canvas* canvas) { | 948 gfx::Canvas* canvas) { |
| 927 // Allow the window blur effect to show through the popup background. | 949 // Allow the window blur effect to show through the popup background. |
| 928 SkPaint paint; | 950 SkPaint paint; |
| 929 SkColor transparency = GetThemeProvider()->ShouldUseNativeFrame() ? | 951 SkColor transparency = GetThemeProvider()->ShouldUseNativeFrame() ? |
| 930 kGlassPopupTransparency : kOpaquePopupTransparency; | 952 kGlassPopupTransparency : kOpaquePopupTransparency; |
| 931 paint.setColor(SkColorSetARGB(transparency, 255, 255, 255)); | 953 paint.setColor(SkColorSetARGB(transparency, 255, 255, 255)); |
| 932 paint.setXfermodeMode(SkXfermode::kDstIn_Mode); | 954 paint.setXfermodeMode(SkXfermode::kDstIn_Mode); |
| 933 paint.setStyle(SkPaint::kFill_Style); | 955 paint.setStyle(SkPaint::kFill_Style); |
| 934 canvas->FillRectInt(0, 0, canvas->getDevice()->width(), | 956 canvas->FillRectInt(0, 0, canvas->getDevice()->width(), |
| 935 canvas->getDevice()->height(), paint); | 957 canvas->getDevice()->height(), paint); |
| 936 } | 958 } |
| 959 |
| 960 // static |
| 961 AutocompletePopupView* AutocompletePopupView::CreatePopupView( |
| 962 const gfx::Font& font, |
| 963 AutocompleteEditView* edit_view, |
| 964 AutocompleteEditModel* edit_model, |
| 965 Profile* profile, |
| 966 AutocompletePopupPositioner* popup_positioner) { |
| 967 return new AutocompletePopupContentsView(font, edit_view, edit_model, |
| 968 profile, popup_positioner); |
| 969 } |
| OLD | NEW |