| 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 // For WinDDK ATL compatibility, these ATL headers must come first. | 5 // For WinDDK ATL compatibility, these ATL headers must come first. |
| 6 #include "build/build_config.h" | 6 #include "build/build_config.h" |
| 7 | 7 |
| 8 #if defined(OS_WIN) | 8 #if defined(OS_WIN) |
| 9 #include <atlbase.h> // NOLINT | 9 #include <atlbase.h> // NOLINT |
| 10 #include <atlwin.h> // NOLINT | 10 #include <atlwin.h> // NOLINT |
| 11 #endif | 11 #endif |
| 12 | 12 |
| 13 #include "base/macros.h" | 13 #include "base/macros.h" |
| 14 #include "chrome/browser/ui/views/omnibox/omnibox_result_view.h" | 14 #include "chrome/browser/ui/views/omnibox/omnibox_result_view.h" |
| 15 | 15 |
| 16 #include <limits.h> | 16 #include <limits.h> |
| 17 | 17 |
| 18 #include <algorithm> // NOLINT | 18 #include <algorithm> // NOLINT |
| 19 | 19 |
| 20 #include "base/i18n/bidi_line_iterator.h" | 20 #include "base/i18n/bidi_line_iterator.h" |
| 21 #include "base/strings/string_number_conversions.h" | 21 #include "base/strings/string_number_conversions.h" |
| 22 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" |
| 23 #include "chrome/browser/ui/layout_constants.h" | 23 #include "chrome/browser/ui/layout_constants.h" |
| 24 #include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h" |
| 24 #include "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h" | 25 #include "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h" |
| 25 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" | 26 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" |
| 26 #include "chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h" | 27 #include "chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h" |
| 27 #include "chrome/grit/generated_resources.h" | 28 #include "chrome/grit/generated_resources.h" |
| 28 #include "components/omnibox/browser/omnibox_popup_model.h" | 29 #include "components/omnibox/browser/omnibox_popup_model.h" |
| 29 #include "grit/components_scaled_resources.h" | 30 #include "grit/components_scaled_resources.h" |
| 30 #include "grit/theme_resources.h" | 31 #include "grit/theme_resources.h" |
| 31 #include "third_party/skia/include/core/SkColor.h" | 32 #include "third_party/skia/include/core/SkColor.h" |
| 32 #include "ui/accessibility/ax_view_state.h" | 33 #include "ui/accessibility/ax_view_state.h" |
| 33 #include "ui/base/l10n/l10n_util.h" | 34 #include "ui/base/l10n/l10n_util.h" |
| 34 #include "ui/base/material_design/material_design_controller.h" | 35 #include "ui/base/material_design/material_design_controller.h" |
| 35 #include "ui/base/resource/resource_bundle.h" | 36 #include "ui/base/resource/resource_bundle.h" |
| 36 #include "ui/base/theme_provider.h" | 37 #include "ui/base/theme_provider.h" |
| 37 #include "ui/gfx/canvas.h" | 38 #include "ui/gfx/canvas.h" |
| 38 #include "ui/gfx/color_palette.h" | 39 #include "ui/gfx/color_palette.h" |
| 39 #include "ui/gfx/color_utils.h" | 40 #include "ui/gfx/color_utils.h" |
| 40 #include "ui/gfx/image/image.h" | 41 #include "ui/gfx/image/image.h" |
| 41 #include "ui/gfx/paint_vector_icon.h" | 42 #include "ui/gfx/paint_vector_icon.h" |
| 42 #include "ui/gfx/range/range.h" | 43 #include "ui/gfx/range/range.h" |
| 43 #include "ui/gfx/render_text.h" | 44 #include "ui/gfx/render_text.h" |
| 45 #include "ui/gfx/scoped_canvas.h" |
| 44 #include "ui/gfx/text_utils.h" | 46 #include "ui/gfx/text_utils.h" |
| 45 #include "ui/gfx/vector_icons_public.h" | 47 #include "ui/gfx/vector_icons_public.h" |
| 46 #include "ui/native_theme/native_theme.h" | 48 #include "ui/native_theme/native_theme.h" |
| 47 | 49 |
| 48 using ui::NativeTheme; | 50 using ui::NativeTheme; |
| 49 | 51 |
| 50 namespace { | 52 namespace { |
| 51 | 53 |
| 52 // A mapping from OmniboxResultView's ResultViewState/ColorKind types to | 54 // A mapping from OmniboxResultView's ResultViewState/ColorKind types to |
| 53 // NativeTheme colors. | 55 // NativeTheme colors. |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 } | 222 } |
| 221 } | 223 } |
| 222 | 224 |
| 223 NOTREACHED(); | 225 NOTREACHED(); |
| 224 return gfx::kPlaceholderColor; | 226 return gfx::kPlaceholderColor; |
| 225 } | 227 } |
| 226 | 228 |
| 227 void OmniboxResultView::SetMatch(const AutocompleteMatch& match) { | 229 void OmniboxResultView::SetMatch(const AutocompleteMatch& match) { |
| 228 match_ = match; | 230 match_ = match; |
| 229 match_.PossiblySwapContentsAndDescriptionForDisplay(); | 231 match_.PossiblySwapContentsAndDescriptionForDisplay(); |
| 230 ResetRenderTexts(); | |
| 231 animation_->Reset(); | 232 animation_->Reset(); |
| 232 answer_image_ = gfx::ImageSkia(); | 233 answer_image_ = gfx::ImageSkia(); |
| 233 | 234 |
| 234 AutocompleteMatch* associated_keyword_match = match_.associated_keyword.get(); | 235 AutocompleteMatch* associated_keyword_match = match_.associated_keyword.get(); |
| 235 if (associated_keyword_match) { | 236 if (associated_keyword_match) { |
| 236 keyword_icon_->SetImage(GetKeywordIcon()); | |
| 237 if (!keyword_icon_->parent()) | 237 if (!keyword_icon_->parent()) |
| 238 AddChildView(keyword_icon_.get()); | 238 AddChildView(keyword_icon_.get()); |
| 239 } else if (keyword_icon_->parent()) { | 239 } else if (keyword_icon_->parent()) { |
| 240 RemoveChildView(keyword_icon_.get()); | 240 RemoveChildView(keyword_icon_.get()); |
| 241 } | 241 } |
| 242 | 242 |
| 243 Invalidate(); |
| 243 if (GetWidget()) | 244 if (GetWidget()) |
| 244 Layout(); | 245 Layout(); |
| 245 } | 246 } |
| 246 | 247 |
| 247 void OmniboxResultView::ShowKeyword(bool show_keyword) { | 248 void OmniboxResultView::ShowKeyword(bool show_keyword) { |
| 248 if (show_keyword) | 249 if (show_keyword) |
| 249 animation_->Show(); | 250 animation_->Show(); |
| 250 else | 251 else |
| 251 animation_->Hide(); | 252 animation_->Hide(); |
| 252 } | 253 } |
| 253 | 254 |
| 254 void OmniboxResultView::Invalidate() { | 255 void OmniboxResultView::Invalidate() { |
| 256 if (ui::MaterialDesignController::IsModeMaterial()) { |
| 257 const ResultViewState state = GetState(); |
| 258 if (state == NORMAL) { |
| 259 set_background(nullptr); |
| 260 } else { |
| 261 const SkColor bg_color = GetColor(state, BACKGROUND); |
| 262 set_background(new BackgroundWith1PxBorder(bg_color, bg_color)); |
| 263 } |
| 264 } |
| 265 |
| 255 keyword_icon_->SetImage(GetKeywordIcon()); | 266 keyword_icon_->SetImage(GetKeywordIcon()); |
| 267 |
| 256 // While the text in the RenderTexts may not have changed, the styling | 268 // While the text in the RenderTexts may not have changed, the styling |
| 257 // (color/bold) may need to change. So we reset them to cause them to be | 269 // (color/bold) may need to change. So we reset them to cause them to be |
| 258 // recomputed in OnPaint(). | 270 // recomputed in OnPaint(). |
| 259 ResetRenderTexts(); | 271 contents_rendertext_.reset(); |
| 260 SchedulePaint(); | 272 description_rendertext_.reset(); |
| 273 separator_rendertext_.reset(); |
| 274 keyword_contents_rendertext_.reset(); |
| 275 keyword_description_rendertext_.reset(); |
| 261 } | 276 } |
| 262 | 277 |
| 263 void OmniboxResultView::OnSelected() { | 278 void OmniboxResultView::OnSelected() { |
| 264 DCHECK_EQ(SELECTED, GetState()); | 279 DCHECK_EQ(SELECTED, GetState()); |
| 265 | 280 |
| 266 // Notify assistive technology when results with answers attached are | 281 // Notify assistive technology when results with answers attached are |
| 267 // selected. The non-answer text is already accessible as a consequence of | 282 // selected. The non-answer text is already accessible as a consequence of |
| 268 // updating the text in the omnibox but this alert and GetAccessibleState | 283 // updating the text in the omnibox but this alert and GetAccessibleState |
| 269 // below make the answer contents accessible. | 284 // below make the answer contents accessible. |
| 270 if (match_.answer) | 285 if (match_.answer) |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 gfx::VectorIconId icon_id) const { | 626 gfx::VectorIconId icon_id) const { |
| 612 return gfx::CreateVectorIcon(icon_id, 16, color_utils::DeriveDefaultIconColor( | 627 return gfx::CreateVectorIcon(icon_id, 16, color_utils::DeriveDefaultIconColor( |
| 613 GetColor(GetState(), TEXT))); | 628 GetColor(GetState(), TEXT))); |
| 614 } | 629 } |
| 615 | 630 |
| 616 bool OmniboxResultView::ShowOnlyKeywordMatch() const { | 631 bool OmniboxResultView::ShowOnlyKeywordMatch() const { |
| 617 return match_.associated_keyword && | 632 return match_.associated_keyword && |
| 618 (keyword_icon_->x() <= icon_bounds_.right()); | 633 (keyword_icon_->x() <= icon_bounds_.right()); |
| 619 } | 634 } |
| 620 | 635 |
| 621 void OmniboxResultView::ResetRenderTexts() const { | |
| 622 contents_rendertext_.reset(); | |
| 623 description_rendertext_.reset(); | |
| 624 separator_rendertext_.reset(); | |
| 625 keyword_contents_rendertext_.reset(); | |
| 626 keyword_description_rendertext_.reset(); | |
| 627 } | |
| 628 | |
| 629 void OmniboxResultView::InitContentsRenderTextIfNecessary() const { | 636 void OmniboxResultView::InitContentsRenderTextIfNecessary() const { |
| 630 if (!contents_rendertext_) { | 637 if (!contents_rendertext_) { |
| 631 contents_rendertext_.reset( | 638 contents_rendertext_.reset( |
| 632 CreateClassifiedRenderText( | 639 CreateClassifiedRenderText( |
| 633 match_.contents, match_.contents_class, false).release()); | 640 match_.contents, match_.contents_class, false).release()); |
| 634 } | 641 } |
| 635 } | 642 } |
| 636 | 643 |
| 637 void OmniboxResultView::Layout() { | 644 void OmniboxResultView::Layout() { |
| 638 const int horizontal_padding = | 645 int horizontal_padding = |
| 639 GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING); | 646 GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING); |
| 640 const int start_x = StartMargin() + horizontal_padding; | 647 // In non-material, the horizontal bounds we're given are indented inside the |
| 641 const int end_x = width() - EndMargin() - horizontal_padding; | 648 // omnibox border. In material, we're given the outside bounds, so we can |
| 649 // match the omnibox border outline shape exactly in OnPaint(). So we have to |
| 650 // inset here to keep the icons lined up. |
| 651 const int border_padding = ui::MaterialDesignController::IsModeMaterial() ? |
| 652 GetLayoutConstant(LOCATION_BAR_BORDER_THICKNESS) : 0; |
| 653 const int start_x = border_padding + horizontal_padding; |
| 654 const int end_x = width() - border_padding - horizontal_padding; |
| 642 | 655 |
| 643 const gfx::ImageSkia icon = GetIcon(); | 656 const gfx::ImageSkia icon = GetIcon(); |
| 644 // Pre-MD, normal icons are 19 px wide, while extension icons are 16 px wide. | 657 // Pre-MD, normal icons are 19 px wide, while extension icons are 16 px wide. |
| 645 // The code in IconLabelBubbleView::Layout() positions these icons in the | 658 // The code in IconLabelBubbleView::Layout() positions these icons in the |
| 646 // omnibox using ICON_LABEL_VIEW_TRAILING_PADDING, so we use that here as well | 659 // omnibox using ICON_LABEL_VIEW_TRAILING_PADDING, so we use that here as well |
| 647 // so the icons will line up. | 660 // so the icons will line up. |
| 648 // | 661 // |
| 649 // Technically we don't need the IsModeMaterial() check here, but it will make | 662 // Technically we don't need the IsModeMaterial() check here, but it will make |
| 650 // it easier to see that all this code is dead once we switch to MD. | 663 // it easier to see that all this code is dead once we switch to MD. |
| 651 int icon_x = start_x; | 664 int icon_x = start_x; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 667 keyword_text_bounds_.SetRect( | 680 keyword_text_bounds_.SetRect( |
| 668 kw_text_x, 0, std::max(end_x - kw_text_x, 0), height()); | 681 kw_text_x, 0, std::max(end_x - kw_text_x, 0), height()); |
| 669 keyword_icon_->SetPosition( | 682 keyword_icon_->SetPosition( |
| 670 gfx::Point(kw_x, (height() - keyword_icon_->height()) / 2)); | 683 gfx::Point(kw_x, (height() - keyword_icon_->height()) / 2)); |
| 671 } | 684 } |
| 672 | 685 |
| 673 text_bounds_.SetRect(text_x, 0, std::max(text_width, 0), height()); | 686 text_bounds_.SetRect(text_x, 0, std::max(text_width, 0), height()); |
| 674 } | 687 } |
| 675 | 688 |
| 676 void OmniboxResultView::OnBoundsChanged(const gfx::Rect& previous_bounds) { | 689 void OmniboxResultView::OnBoundsChanged(const gfx::Rect& previous_bounds) { |
| 677 animation_->SetSlideDuration((width() - StartMargin() - EndMargin()) / 4); | 690 animation_->SetSlideDuration(width() / 4); |
| 678 } | 691 } |
| 679 | 692 |
| 680 void OmniboxResultView::OnPaint(gfx::Canvas* canvas) { | 693 void OmniboxResultView::OnPaint(gfx::Canvas* canvas) { |
| 681 const ResultViewState state = GetState(); | 694 if (ui::MaterialDesignController::IsModeMaterial()) { |
| 682 if (state != NORMAL) | 695 View::OnPaint(canvas); |
| 683 canvas->DrawColor(GetColor(state, BACKGROUND)); | 696 } else { |
| 697 const ResultViewState state = GetState(); |
| 698 if (state != NORMAL) |
| 699 canvas->DrawColor(GetColor(state, BACKGROUND)); |
| 700 } |
| 684 | 701 |
| 685 // NOTE: While animating the keyword match, both matches may be visible. | 702 // NOTE: While animating the keyword match, both matches may be visible. |
| 686 | 703 |
| 687 if (!ShowOnlyKeywordMatch()) { | 704 if (!ShowOnlyKeywordMatch()) { |
| 688 canvas->DrawImageInt(GetIcon(), GetMirroredXForRect(icon_bounds_), | 705 canvas->DrawImageInt(GetIcon(), GetMirroredXForRect(icon_bounds_), |
| 689 icon_bounds_.y()); | 706 icon_bounds_.y()); |
| 690 int x = GetMirroredXForRect(text_bounds_); | 707 int x = GetMirroredXForRect(text_bounds_); |
| 691 mirroring_context_->Initialize(x, text_bounds_.width()); | 708 mirroring_context_->Initialize(x, text_bounds_.width()); |
| 692 InitContentsRenderTextIfNecessary(); | 709 InitContentsRenderTextIfNecessary(); |
| 693 | 710 |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 destination->AppendText(text); | 836 destination->AppendText(text); |
| 820 const TextStyle& text_style = GetTextStyle(text_type); | 837 const TextStyle& text_style = GetTextStyle(text_type); |
| 821 // TODO(dschuyler): follow up on the problem of different font sizes within | 838 // TODO(dschuyler): follow up on the problem of different font sizes within |
| 822 // one RenderText. Maybe with destination->SetFontList(...). | 839 // one RenderText. Maybe with destination->SetFontList(...). |
| 823 destination->ApplyWeight( | 840 destination->ApplyWeight( |
| 824 is_bold ? gfx::Font::Weight::BOLD : gfx::Font::Weight::NORMAL, range); | 841 is_bold ? gfx::Font::Weight::BOLD : gfx::Font::Weight::NORMAL, range); |
| 825 destination->ApplyColor( | 842 destination->ApplyColor( |
| 826 GetNativeTheme()->GetSystemColor(text_style.colors[GetState()]), range); | 843 GetNativeTheme()->GetSystemColor(text_style.colors[GetState()]), range); |
| 827 destination->ApplyBaselineStyle(text_style.baseline, range); | 844 destination->ApplyBaselineStyle(text_style.baseline, range); |
| 828 } | 845 } |
| 829 | |
| 830 int OmniboxResultView::StartMargin() const { | |
| 831 return ui::MaterialDesignController::IsModeMaterial() ? | |
| 832 model_->start_margin() : 0; | |
| 833 } | |
| 834 | |
| 835 int OmniboxResultView::EndMargin() const { | |
| 836 return ui::MaterialDesignController::IsModeMaterial() ? | |
| 837 model_->end_margin() : 0; | |
| 838 } | |
| OLD | NEW |