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 |
(...skipping 30 matching lines...) Expand all Loading... | |
41 #include "ui/gfx/range/range.h" | 41 #include "ui/gfx/range/range.h" |
42 #include "ui/gfx/render_text.h" | 42 #include "ui/gfx/render_text.h" |
43 #include "ui/gfx/text_utils.h" | 43 #include "ui/gfx/text_utils.h" |
44 #include "ui/gfx/vector_icons_public.h" | 44 #include "ui/gfx/vector_icons_public.h" |
45 #include "ui/native_theme/native_theme.h" | 45 #include "ui/native_theme/native_theme.h" |
46 | 46 |
47 using ui::NativeTheme; | 47 using ui::NativeTheme; |
48 | 48 |
49 namespace { | 49 namespace { |
50 | 50 |
51 // Don't trust the number of lines from AiS. Cap it. | |
52 constexpr int kMAX_DISPLAY_LINES = 3; | |
Peter Kasting
2016/06/01 16:15:29
Nit: Declare this in the lone scope where it's use
Kevin Bailey
2016/06/01 17:33:59
Done.
| |
53 | |
51 // A mapping from OmniboxResultView's ResultViewState/ColorKind types to | 54 // A mapping from OmniboxResultView's ResultViewState/ColorKind types to |
52 // NativeTheme colors. | 55 // NativeTheme colors. |
53 struct TranslationTable { | 56 struct TranslationTable { |
54 ui::NativeTheme::ColorId id; | 57 ui::NativeTheme::ColorId id; |
55 OmniboxResultView::ResultViewState state; | 58 OmniboxResultView::ResultViewState state; |
56 OmniboxResultView::ColorKind kind; | 59 OmniboxResultView::ColorKind kind; |
57 } static const kTranslationTable[] = { | 60 } static const kTranslationTable[] = { |
58 { NativeTheme::kColorId_ResultsTableNormalBackground, | 61 { NativeTheme::kColorId_ResultsTableNormalBackground, |
59 OmniboxResultView::NORMAL, OmniboxResultView::BACKGROUND }, | 62 OmniboxResultView::NORMAL, OmniboxResultView::BACKGROUND }, |
60 { NativeTheme::kColorId_ResultsTableHoveredBackground, | 63 { NativeTheme::kColorId_ResultsTableHoveredBackground, |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
271 // updating the text in the omnibox but this alert and GetAccessibleState | 274 // updating the text in the omnibox but this alert and GetAccessibleState |
272 // below make the answer contents accessible. | 275 // below make the answer contents accessible. |
273 if (match_.answer) | 276 if (match_.answer) |
274 NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true); | 277 NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true); |
275 } | 278 } |
276 | 279 |
277 gfx::Size OmniboxResultView::GetPreferredSize() const { | 280 gfx::Size OmniboxResultView::GetPreferredSize() const { |
278 if (!match_.answer) | 281 if (!match_.answer) |
279 return gfx::Size(0, GetContentLineHeight()); | 282 return gfx::Size(0, GetContentLineHeight()); |
280 // An answer implies a match and a description in a large font. | 283 // An answer implies a match and a description in a large font. |
281 return gfx::Size(0, GetContentLineHeight() + GetAnswerLineHeight()); | 284 const auto& text_fields = match_.answer->second_line().text_fields(); |
285 if (!text_fields.empty() && text_fields[0].has_num_lines()) { | |
Peter Kasting
2016/06/01 16:15:29
Nit: You use [0] here and .front() below. Pick on
Kevin Bailey
2016/06/01 17:34:00
Done.
| |
286 if (!description_rendertext_) | |
Peter Kasting
2016/06/01 16:15:29
Nit: {}
Kevin Bailey
2016/06/01 17:34:00
Done.
| |
287 description_rendertext_ = | |
288 CreateAnswerLine(match_.answer->second_line(), font_list_); | |
289 description_rendertext_->SetDisplayRect( | |
290 gfx::Rect(text_bounds().width(), 0)); | |
Peter Kasting
2016/06/01 16:15:29
Nit: Prefer text_bounds_
Kevin Bailey
2016/06/01 17:34:00
This one surprises me, particularly since 'text_bo
| |
291 description_rendertext_->GetStringSize(); | |
292 return gfx::Size( | |
293 0, GetContentLineHeight() + | |
294 GetAnswerLineHeight() * description_rendertext_->GetNumLines()); | |
295 } else { | |
296 return gfx::Size(0, GetContentLineHeight() + GetAnswerLineHeight()); | |
Peter Kasting
2016/06/01 16:15:29
Nit: Reverse the conditional above and do this as
Kevin Bailey
2016/06/01 17:34:00
Done.
| |
297 } | |
282 } | 298 } |
283 | 299 |
284 void OmniboxResultView::GetAccessibleState(ui::AXViewState* state) { | 300 void OmniboxResultView::GetAccessibleState(ui::AXViewState* state) { |
285 state->name = match_.answer | 301 state->name = match_.answer |
286 ? l10n_util::GetStringFUTF16( | 302 ? l10n_util::GetStringFUTF16( |
287 IDS_OMNIBOX_ACCESSIBLE_ANSWER, match_.contents, | 303 IDS_OMNIBOX_ACCESSIBLE_ANSWER, match_.contents, |
288 match_.answer->second_line().AccessibleText()) | 304 match_.answer->second_line().AccessibleText()) |
289 : match_.contents; | 305 : match_.contents; |
290 } | 306 } |
291 | 307 |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
423 gfx::DIRECTIONALITY_FORCE_RTL : gfx::DIRECTIONALITY_FORCE_LTR); | 439 gfx::DIRECTIONALITY_FORCE_RTL : gfx::DIRECTIONALITY_FORCE_LTR); |
424 prefix_render_text->SetHorizontalAlignment( | 440 prefix_render_text->SetHorizontalAlignment( |
425 is_match_contents_rtl ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT); | 441 is_match_contents_rtl ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT); |
426 prefix_render_text->SetDisplayRect( | 442 prefix_render_text->SetDisplayRect( |
427 gfx::Rect(mirroring_context_->mirrored_left_coord( | 443 gfx::Rect(mirroring_context_->mirrored_left_coord( |
428 prefix_x, prefix_x + prefix_width), | 444 prefix_x, prefix_x + prefix_width), |
429 y, prefix_width, GetContentLineHeight())); | 445 y, prefix_width, GetContentLineHeight())); |
430 prefix_render_text->Draw(canvas); | 446 prefix_render_text->Draw(canvas); |
431 } | 447 } |
432 | 448 |
433 // Set the display rect to trigger eliding. | 449 // Set the display rect to trigger elision. |
434 const int height = (render_text_type == DESCRIPTION && match.answer) ? | 450 int final_width = right_x - x; |
Peter Kasting
2016/06/01 16:15:29
Nit: const?
Kevin Bailey
2016/06/01 17:34:00
Done.
| |
435 GetAnswerLineHeight() : GetContentLineHeight(); | 451 int height = GetContentLineHeight(); |
452 if (render_text_type == DESCRIPTION && match.answer) { | |
453 render_text->SetDisplayRect(gfx::Rect(gfx::Size(final_width, 0))); | |
454 render_text->GetStringSize(); | |
455 height = GetAnswerLineHeight() * render_text->GetNumLines(); | |
456 } | |
436 render_text->SetDisplayRect( | 457 render_text->SetDisplayRect( |
437 gfx::Rect(mirroring_context_->mirrored_left_coord(x, right_x), y, | 458 gfx::Rect(mirroring_context_->mirrored_left_coord(x, right_x), y, |
438 right_x - x, height)); | 459 final_width, height)); |
439 render_text->Draw(canvas); | 460 render_text->Draw(canvas); |
440 return right_x; | 461 return right_x; |
441 } | 462 } |
442 | 463 |
443 std::unique_ptr<gfx::RenderText> OmniboxResultView::CreateRenderText( | 464 std::unique_ptr<gfx::RenderText> OmniboxResultView::CreateRenderText( |
444 const base::string16& text) const { | 465 const base::string16& text) const { |
445 std::unique_ptr<gfx::RenderText> render_text( | 466 std::unique_ptr<gfx::RenderText> render_text( |
446 gfx::RenderText::CreateInstance()); | 467 gfx::RenderText::CreateInstance()); |
447 render_text->SetDisplayRect(gfx::Rect(gfx::Size(INT_MAX, 0))); | 468 render_text->SetDisplayRect(gfx::Rect(gfx::Size(INT_MAX, 0))); |
448 render_text->SetCursorEnabled(false); | 469 render_text->SetCursorEnabled(false); |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
674 canvas->DrawImageInt(GetIcon(), GetMirroredXForRect(icon_bounds_), | 695 canvas->DrawImageInt(GetIcon(), GetMirroredXForRect(icon_bounds_), |
675 icon_bounds_.y()); | 696 icon_bounds_.y()); |
676 int x = GetMirroredXForRect(text_bounds_); | 697 int x = GetMirroredXForRect(text_bounds_); |
677 mirroring_context_->Initialize(x, text_bounds_.width()); | 698 mirroring_context_->Initialize(x, text_bounds_.width()); |
678 InitContentsRenderTextIfNecessary(); | 699 InitContentsRenderTextIfNecessary(); |
679 | 700 |
680 if (!description_rendertext_) { | 701 if (!description_rendertext_) { |
681 if (match_.answer) { | 702 if (match_.answer) { |
682 contents_rendertext_ = | 703 contents_rendertext_ = |
683 CreateAnswerLine(match_.answer->first_line(), font_list_); | 704 CreateAnswerLine(match_.answer->first_line(), font_list_); |
684 description_rendertext_ = CreateAnswerLine( | 705 description_rendertext_ = |
685 match_.answer->second_line(), | 706 CreateAnswerLine(match_.answer->second_line(), font_list_); |
686 ui::ResourceBundle::GetSharedInstance().GetFontList( | |
687 ui::ResourceBundle::LargeFont)); | |
688 } else if (!match_.description.empty()) { | 707 } else if (!match_.description.empty()) { |
689 description_rendertext_ = CreateClassifiedRenderText( | 708 description_rendertext_ = CreateClassifiedRenderText( |
690 match_.description, match_.description_class, true); | 709 match_.description, match_.description_class, true); |
691 } | 710 } |
692 } | 711 } |
693 PaintMatch(match_, contents_rendertext_.get(), | 712 PaintMatch(match_, contents_rendertext_.get(), |
694 description_rendertext_.get(), canvas, x); | 713 description_rendertext_.get(), canvas, x); |
695 } | 714 } |
696 | 715 |
697 AutocompleteMatch* keyword_match = match_.associated_keyword.get(); | 716 AutocompleteMatch* keyword_match = match_.associated_keyword.get(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
730 } | 749 } |
731 | 750 |
732 int OmniboxResultView::GetContentLineHeight() const { | 751 int OmniboxResultView::GetContentLineHeight() const { |
733 return std::max( | 752 return std::max( |
734 default_icon_size_ + GetLayoutInsets(OMNIBOX_DROPDOWN_ICON).height(), | 753 default_icon_size_ + GetLayoutInsets(OMNIBOX_DROPDOWN_ICON).height(), |
735 GetTextHeight() + GetLayoutInsets(OMNIBOX_DROPDOWN_TEXT).height()); | 754 GetTextHeight() + GetLayoutInsets(OMNIBOX_DROPDOWN_TEXT).height()); |
736 } | 755 } |
737 | 756 |
738 std::unique_ptr<gfx::RenderText> OmniboxResultView::CreateAnswerLine( | 757 std::unique_ptr<gfx::RenderText> OmniboxResultView::CreateAnswerLine( |
739 const SuggestionAnswer::ImageLine& line, | 758 const SuggestionAnswer::ImageLine& line, |
740 gfx::FontList font_list) { | 759 gfx::FontList font_list) const { |
741 std::unique_ptr<gfx::RenderText> destination = | 760 std::unique_ptr<gfx::RenderText> destination = |
742 CreateRenderText(base::string16()); | 761 CreateRenderText(base::string16()); |
743 destination->SetFontList(font_list); | 762 destination->SetFontList(font_list); |
744 | 763 |
745 for (const SuggestionAnswer::TextField& text_field : line.text_fields()) | 764 for (const SuggestionAnswer::TextField& text_field : line.text_fields()) |
Kevin Bailey
2016/06/01 14:56:36
Am I the only bothered by the same variable being
Peter Kasting
2016/06/01 16:15:29
Well, it's really 3 variables due to scoping.
If
Kevin Bailey
2016/06/01 17:33:59
I took care of one, but the others didn't seem lik
Justin Donnelly
2016/06/01 17:38:17
To me a variable named after its type is just sayi
| |
746 AppendAnswerText(destination.get(), text_field.text(), text_field.type()); | 765 AppendAnswerText(destination.get(), text_field.text(), text_field.type()); |
766 if (!line.text_fields().empty()) { | |
767 const SuggestionAnswer::TextField& text_field = line.text_fields().front(); | |
768 if (text_field.has_num_lines() && text_field.num_lines() > 1 && | |
769 destination->MultilineSupported()) { | |
770 destination->SetMultiline(true); | |
771 destination->SetMaxLines( | |
772 std::min(kMAX_DISPLAY_LINES, text_field.num_lines())); | |
773 } | |
774 } | |
747 const base::char16 space(' '); | 775 const base::char16 space(' '); |
748 const auto* text_field = line.additional_text(); | 776 const auto* text_field = line.additional_text(); |
749 if (text_field) { | 777 if (text_field) { |
750 AppendAnswerText(destination.get(), space + text_field->text(), | 778 AppendAnswerText(destination.get(), space + text_field->text(), |
751 text_field->type()); | 779 text_field->type()); |
752 } | 780 } |
753 text_field = line.status_text(); | 781 text_field = line.status_text(); |
754 if (text_field) { | 782 if (text_field) { |
755 AppendAnswerText(destination.get(), space + text_field->text(), | 783 AppendAnswerText(destination.get(), space + text_field->text(), |
756 text_field->type()); | 784 text_field->type()); |
757 } | 785 } |
758 return destination; | 786 return destination; |
759 } | 787 } |
760 | 788 |
761 void OmniboxResultView::AppendAnswerText(gfx::RenderText* destination, | 789 void OmniboxResultView::AppendAnswerText(gfx::RenderText* destination, |
762 const base::string16& text, | 790 const base::string16& text, |
763 int text_type) { | 791 int text_type) const { |
764 // TODO(dschuyler): make this better. Right now this only supports unnested | 792 // TODO(dschuyler): make this better. Right now this only supports unnested |
765 // bold tags. In the future we'll need to flag unexpected tags while adding | 793 // bold tags. In the future we'll need to flag unexpected tags while adding |
766 // support for b, i, u, sub, and sup. We'll also need to support HTML | 794 // support for b, i, u, sub, and sup. We'll also need to support HTML |
767 // entities (< for '<', etc.). | 795 // entities (< for '<', etc.). |
768 const base::string16 begin_tag = base::ASCIIToUTF16("<b>"); | 796 const base::string16 begin_tag = base::ASCIIToUTF16("<b>"); |
769 const base::string16 end_tag = base::ASCIIToUTF16("</b>"); | 797 const base::string16 end_tag = base::ASCIIToUTF16("</b>"); |
770 size_t begin = 0; | 798 size_t begin = 0; |
771 while (true) { | 799 while (true) { |
772 size_t end = text.find(begin_tag, begin); | 800 size_t end = text.find(begin_tag, begin); |
773 if (end == base::string16::npos) { | 801 if (end == base::string16::npos) { |
774 AppendAnswerTextHelper(destination, text.substr(begin), text_type, false); | 802 AppendAnswerTextHelper(destination, text.substr(begin), text_type, false); |
775 break; | 803 break; |
776 } | 804 } |
777 AppendAnswerTextHelper(destination, text.substr(begin, end - begin), | 805 AppendAnswerTextHelper(destination, text.substr(begin, end - begin), |
778 text_type, false); | 806 text_type, false); |
779 begin = end + begin_tag.length(); | 807 begin = end + begin_tag.length(); |
780 end = text.find(end_tag, begin); | 808 end = text.find(end_tag, begin); |
781 if (end == base::string16::npos) | 809 if (end == base::string16::npos) |
782 break; | 810 break; |
783 AppendAnswerTextHelper(destination, text.substr(begin, end - begin), | 811 AppendAnswerTextHelper(destination, text.substr(begin, end - begin), |
784 text_type, true); | 812 text_type, true); |
785 begin = end + end_tag.length(); | 813 begin = end + end_tag.length(); |
786 } | 814 } |
787 } | 815 } |
788 | 816 |
789 void OmniboxResultView::AppendAnswerTextHelper(gfx::RenderText* destination, | 817 void OmniboxResultView::AppendAnswerTextHelper(gfx::RenderText* destination, |
790 const base::string16& text, | 818 const base::string16& text, |
791 int text_type, | 819 int text_type, |
792 bool is_bold) { | 820 bool is_bold) const { |
793 if (text.empty()) | 821 if (text.empty()) |
794 return; | 822 return; |
795 int offset = destination->text().length(); | 823 int offset = destination->text().length(); |
796 gfx::Range range(offset, offset + text.length()); | 824 gfx::Range range(offset, offset + text.length()); |
797 destination->AppendText(text); | 825 destination->AppendText(text); |
798 const TextStyle& text_style = GetTextStyle(text_type); | 826 const TextStyle& text_style = GetTextStyle(text_type); |
799 // TODO(dschuyler): follow up on the problem of different font sizes within | 827 // TODO(dschuyler): follow up on the problem of different font sizes within |
800 // one RenderText. Maybe with destination->SetFontList(...). | 828 // one RenderText. Maybe with destination->SetFontList(...). |
801 destination->ApplyStyle(gfx::BOLD, is_bold, range); | 829 destination->ApplyStyle(gfx::BOLD, is_bold, range); |
802 destination->ApplyColor( | 830 destination->ApplyColor( |
803 GetNativeTheme()->GetSystemColor(text_style.colors[GetState()]), range); | 831 GetNativeTheme()->GetSystemColor(text_style.colors[GetState()]), range); |
804 destination->ApplyBaselineStyle(text_style.baseline, range); | 832 destination->ApplyBaselineStyle(text_style.baseline, range); |
805 } | 833 } |
806 | 834 |
807 int OmniboxResultView::StartMargin() const { | 835 int OmniboxResultView::StartMargin() const { |
808 return ui::MaterialDesignController::IsModeMaterial() ? | 836 return ui::MaterialDesignController::IsModeMaterial() ? |
809 model_->start_margin() : 0; | 837 model_->start_margin() : 0; |
810 } | 838 } |
811 | 839 |
812 int OmniboxResultView::EndMargin() const { | 840 int OmniboxResultView::EndMargin() const { |
813 return ui::MaterialDesignController::IsModeMaterial() ? | 841 return ui::MaterialDesignController::IsModeMaterial() ? |
814 model_->end_margin() : 0; | 842 model_->end_margin() : 0; |
815 } | 843 } |
OLD | NEW |