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 // 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 43 #include "ui/gfx/paint_vector_icon.h" | 43 #include "ui/gfx/paint_vector_icon.h" |
| 44 #include "ui/gfx/range/range.h" | 44 #include "ui/gfx/range/range.h" |
| 45 #include "ui/gfx/render_text.h" | 45 #include "ui/gfx/render_text.h" |
| 46 #include "ui/gfx/text_utils.h" | 46 #include "ui/gfx/text_utils.h" |
| 47 #include "ui/native_theme/native_theme.h" | 47 #include "ui/native_theme/native_theme.h" |
| 48 | 48 |
| 49 using ui::NativeTheme; | 49 using ui::NativeTheme; |
| 50 | 50 |
| 51 namespace { | 51 namespace { |
| 52 | 52 |
| 53 // The padding that should be placed between content and description in a | 53 // The vertical margin that should be used above and below each suggestion. |
| 54 // vertical layout. | 54 static const int kVerticalMargin = 1; |
| 55 static const int kVerticalPadding = 3; | 55 |
| 56 // The vertical padding to provide each RenderText in addition to the height of | |
| 57 // the font. Where possible, RenderText uses this additional space to vertically | |
| 58 // center the cap height of the font instead of centering the entire font. | |
| 59 static const int kVerticalPadding = 4; | |
| 56 | 60 |
| 57 // A mapping from OmniboxResultView's ResultViewState/ColorKind types to | 61 // A mapping from OmniboxResultView's ResultViewState/ColorKind types to |
| 58 // NativeTheme colors. | 62 // NativeTheme colors. |
| 59 struct TranslationTable { | 63 struct TranslationTable { |
| 60 ui::NativeTheme::ColorId id; | 64 ui::NativeTheme::ColorId id; |
| 61 OmniboxResultView::ResultViewState state; | 65 OmniboxResultView::ResultViewState state; |
| 62 OmniboxResultView::ColorKind kind; | 66 OmniboxResultView::ColorKind kind; |
| 63 } static const kTranslationTable[] = { | 67 } static const kTranslationTable[] = { |
| 64 { NativeTheme::kColorId_ResultsTableNormalBackground, | 68 { NativeTheme::kColorId_ResultsTableNormalBackground, |
| 65 OmniboxResultView::NORMAL, OmniboxResultView::BACKGROUND }, | 69 OmniboxResultView::NORMAL, OmniboxResultView::BACKGROUND }, |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 296 // selected. The non-answer text is already accessible as a consequence of | 300 // selected. The non-answer text is already accessible as a consequence of |
| 297 // updating the text in the omnibox but this alert and GetAccessibleNodeData | 301 // updating the text in the omnibox but this alert and GetAccessibleNodeData |
| 298 // below make the answer contents accessible. | 302 // below make the answer contents accessible. |
| 299 if (match_.answer) | 303 if (match_.answer) |
| 300 NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true); | 304 NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true); |
| 301 } | 305 } |
| 302 | 306 |
| 303 gfx::Size OmniboxResultView::CalculatePreferredSize() const { | 307 gfx::Size OmniboxResultView::CalculatePreferredSize() const { |
| 304 int height = GetTextHeight() + (2 * GetVerticalMargin()); | 308 int height = GetTextHeight() + (2 * GetVerticalMargin()); |
| 305 if (match_.answer) | 309 if (match_.answer) |
| 306 height += GetAnswerHeight() + kVerticalPadding; | 310 height += GetAnswerHeight(); |
| 307 else if (base::FeatureList::IsEnabled(omnibox::kUIExperimentVerticalLayout)) | 311 else if (base::FeatureList::IsEnabled(omnibox::kUIExperimentVerticalLayout)) |
| 308 height += GetTextHeight() + kVerticalPadding; | 312 height += GetTextHeight(); |
| 309 return gfx::Size(0, height); | 313 return gfx::Size(0, height); |
| 310 } | 314 } |
| 311 | 315 |
| 312 void OmniboxResultView::GetAccessibleNodeData(ui::AXNodeData* node_data) { | 316 void OmniboxResultView::GetAccessibleNodeData(ui::AXNodeData* node_data) { |
| 313 node_data->SetName(match_.answer | 317 node_data->SetName(match_.answer |
| 314 ? l10n_util::GetStringFUTF16( | 318 ? l10n_util::GetStringFUTF16( |
| 315 IDS_OMNIBOX_ACCESSIBLE_ANSWER, match_.contents, | 319 IDS_OMNIBOX_ACCESSIBLE_ANSWER, match_.contents, |
| 316 match_.answer->second_line().AccessibleText()) | 320 match_.answer->second_line().AccessibleText()) |
| 317 : match_.contents); | 321 : match_.contents); |
| 318 } | 322 } |
| 319 | 323 |
| 320 void OmniboxResultView::OnNativeThemeChanged(const ui::NativeTheme* theme) { | 324 void OmniboxResultView::OnNativeThemeChanged(const ui::NativeTheme* theme) { |
| 321 Invalidate(); | 325 Invalidate(); |
| 322 SchedulePaint(); | 326 SchedulePaint(); |
| 323 } | 327 } |
| 324 | 328 |
| 325 //////////////////////////////////////////////////////////////////////////////// | 329 //////////////////////////////////////////////////////////////////////////////// |
| 326 // OmniboxResultView, protected: | 330 // OmniboxResultView, protected: |
| 327 | 331 |
| 328 OmniboxResultView::ResultViewState OmniboxResultView::GetState() const { | 332 OmniboxResultView::ResultViewState OmniboxResultView::GetState() const { |
| 329 if (model_->IsSelectedIndex(model_index_)) | 333 if (model_->IsSelectedIndex(model_index_)) |
| 330 return SELECTED; | 334 return SELECTED; |
| 331 return model_->IsHoveredIndex(model_index_) ? HOVERED : NORMAL; | 335 return model_->IsHoveredIndex(model_index_) ? HOVERED : NORMAL; |
| 332 } | 336 } |
| 333 | 337 |
| 334 int OmniboxResultView::GetTextHeight() const { | 338 int OmniboxResultView::GetTextHeight() const { |
| 335 return font_height_; | 339 return font_height_ + kVerticalPadding; |
| 336 } | 340 } |
| 337 | 341 |
| 338 void OmniboxResultView::PaintMatch(const AutocompleteMatch& match, | 342 void OmniboxResultView::PaintMatch(const AutocompleteMatch& match, |
| 339 gfx::RenderText* contents, | 343 gfx::RenderText* contents, |
| 340 gfx::RenderText* description, | 344 gfx::RenderText* description, |
| 341 gfx::Canvas* canvas, | 345 gfx::Canvas* canvas, |
| 342 int x) const { | 346 int x) const { |
| 343 int y = text_bounds_.y() + GetVerticalMargin(); | 347 int y = text_bounds_.y() + GetVerticalMargin(); |
| 344 | 348 |
| 345 if (!separator_rendertext_) { | 349 if (!separator_rendertext_) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 360 OmniboxPopupModel::ComputeMatchMaxWidths( | 364 OmniboxPopupModel::ComputeMatchMaxWidths( |
| 361 contents->GetContentWidth(), separator_width_, | 365 contents->GetContentWidth(), separator_width_, |
| 362 description ? description->GetContentWidth() : 0, | 366 description ? description->GetContentWidth() : 0, |
| 363 mirroring_context_->remaining_width(x), description_on_separate_line, | 367 mirroring_context_->remaining_width(x), description_on_separate_line, |
| 364 !AutocompleteMatch::IsSearchType(match.type), &contents_max_width, | 368 !AutocompleteMatch::IsSearchType(match.type), &contents_max_width, |
| 365 &description_max_width); | 369 &description_max_width); |
| 366 | 370 |
| 367 // Answers in Suggest results. | 371 // Answers in Suggest results. |
| 368 if (match.answer && description_max_width != 0) { | 372 if (match.answer && description_max_width != 0) { |
| 369 DrawRenderText(match, contents, CONTENTS, canvas, x, y, contents_max_width); | 373 DrawRenderText(match, contents, CONTENTS, canvas, x, y, contents_max_width); |
| 370 y += GetTextHeight() + kVerticalPadding; | 374 y += GetTextHeight(); |
| 371 if (!answer_image_.isNull()) { | 375 if (!answer_image_.isNull()) { |
| 372 int answer_icon_size = GetAnswerHeight(); | 376 int answer_icon_size = GetAnswerFont().GetHeight(); |
|
Peter Kasting
2017/06/15 22:43:34
Nit: Is it worth commenting here why using GetAnsw
Justin Donnelly
2017/06/16 14:14:31
Done.
| |
| 373 canvas->DrawImageInt(answer_image_, 0, 0, answer_image_.width(), | 377 canvas->DrawImageInt(answer_image_, 0, 0, answer_image_.width(), |
| 374 answer_image_.height(), GetMirroredXInView(x), y, | 378 answer_image_.height(), GetMirroredXInView(x), |
| 375 answer_icon_size, answer_icon_size, true); | 379 y + (kVerticalPadding / 2), answer_icon_size, |
| 380 answer_icon_size, true); | |
| 376 // TODO(dschuyler): Perhaps this should be based on the font size | 381 // TODO(dschuyler): Perhaps this should be based on the font size |
| 377 // instead of hardcoded to 2 dp (e.g. by adding a space in an | 382 // instead of hardcoded to 2 dp (e.g. by adding a space in an |
| 378 // appropriate font to the beginning of the description, then reducing | 383 // appropriate font to the beginning of the description, then reducing |
| 379 // the additional padding here to zero). | 384 // the additional padding here to zero). |
| 380 const int kAnswerIconToTextPadding = 2; | 385 const int kAnswerIconToTextPadding = 2; |
| 381 x += answer_icon_size + kAnswerIconToTextPadding; | 386 x += answer_icon_size + kAnswerIconToTextPadding; |
| 382 } | 387 } |
| 383 DrawRenderText(match, description, DESCRIPTION, canvas, x, y, | 388 DrawRenderText(match, description, DESCRIPTION, canvas, x, y, |
| 384 description_max_width); | 389 description_max_width); |
| 385 return; | 390 return; |
| 386 } | 391 } |
| 387 | 392 |
| 388 // Regular results. | 393 // Regular results. |
| 389 if (base::FeatureList::IsEnabled(omnibox::kUIExperimentVerticalLayout)) { | 394 if (base::FeatureList::IsEnabled(omnibox::kUIExperimentVerticalLayout)) { |
| 390 // For no description, shift down halfways to draw contents in middle. | 395 // For no description, shift down halfways to draw contents in middle. |
| 391 if (description_max_width == 0) | 396 if (description_max_width == 0) |
| 392 y += (GetTextHeight() + kVerticalPadding) / 2; | 397 y += GetTextHeight() / 2; |
| 393 | 398 |
| 394 DrawRenderText(match, contents, CONTENTS, canvas, x, y, contents_max_width); | 399 DrawRenderText(match, contents, CONTENTS, canvas, x, y, contents_max_width); |
| 395 | 400 |
| 396 if (description_max_width != 0) { | 401 if (description_max_width != 0) { |
| 397 y += GetTextHeight() + kVerticalPadding; | 402 y += GetTextHeight(); |
| 398 DrawRenderText(match, description, DESCRIPTION, canvas, x, y, | 403 DrawRenderText(match, description, DESCRIPTION, canvas, x, y, |
| 399 description_max_width); | 404 description_max_width); |
| 400 } | 405 } |
| 401 } else { | 406 } else { |
| 402 x = DrawRenderText(match, contents, CONTENTS, canvas, x, y, | 407 x = DrawRenderText(match, contents, CONTENTS, canvas, x, y, |
| 403 contents_max_width); | 408 contents_max_width); |
| 404 if (description_max_width != 0) { | 409 if (description_max_width != 0) { |
| 405 x = DrawRenderText(match, separator_rendertext_.get(), SEPARATOR, canvas, | 410 x = DrawRenderText(match, separator_rendertext_.get(), SEPARATOR, canvas, |
| 406 x, y, separator_width_); | 411 x, y, separator_width_); |
| 407 DrawRenderText(match, description, DESCRIPTION, canvas, x, y, | 412 DrawRenderText(match, description, DESCRIPTION, canvas, x, y, |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 640 // the omnibox border outline shape exactly in OnPaint(). We have to inset | 645 // the omnibox border outline shape exactly in OnPaint(). We have to inset |
| 641 // here to keep the icons lined up. | 646 // here to keep the icons lined up. |
| 642 const int start_x = BackgroundWith1PxBorder::kLocationBarBorderThicknessDip + | 647 const int start_x = BackgroundWith1PxBorder::kLocationBarBorderThicknessDip + |
| 643 horizontal_padding; | 648 horizontal_padding; |
| 644 const int end_x = width() - start_x; | 649 const int end_x = width() - start_x; |
| 645 | 650 |
| 646 const gfx::ImageSkia icon = GetIcon(); | 651 const gfx::ImageSkia icon = GetIcon(); |
| 647 | 652 |
| 648 int row_height = GetTextHeight(); | 653 int row_height = GetTextHeight(); |
| 649 if (base::FeatureList::IsEnabled(omnibox::kUIExperimentVerticalLayout)) | 654 if (base::FeatureList::IsEnabled(omnibox::kUIExperimentVerticalLayout)) |
| 650 row_height += kVerticalPadding + GetTextHeight(); | 655 row_height += match_.answer ? GetAnswerHeight() : GetTextHeight(); |
| 651 | 656 |
| 652 const int icon_y = GetVerticalMargin() + (row_height - icon.height()) / 2; | 657 const int icon_y = GetVerticalMargin() + (row_height - icon.height()) / 2; |
| 653 icon_bounds_.SetRect(start_x, icon_y, icon.width(), icon.height()); | 658 icon_bounds_.SetRect(start_x, icon_y, icon.width(), icon.height()); |
| 654 | 659 |
| 655 const int text_x = start_x + LocationBarView::kIconWidth + horizontal_padding; | 660 const int text_x = start_x + LocationBarView::kIconWidth + horizontal_padding; |
| 656 int text_width = end_x - text_x; | 661 int text_width = end_x - text_x; |
| 657 | 662 |
| 658 if (match_.associated_keyword.get()) { | 663 if (match_.associated_keyword.get()) { |
| 659 const int max_kw_x = end_x - keyword_icon_->width(); | 664 const int max_kw_x = end_x - keyword_icon_->width(); |
| 660 const int kw_x = animation_->CurrentValueBetween(max_kw_x, start_x); | 665 const int kw_x = animation_->CurrentValueBetween(max_kw_x, start_x); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 740 ? match_.answer->second_line().text_fields()[0].type() | 745 ? match_.answer->second_line().text_fields()[0].type() |
| 741 : SuggestionAnswer::SUGGESTION; | 746 : SuggestionAnswer::SUGGESTION; |
| 742 return ui::ResourceBundle::GetSharedInstance().GetFontList( | 747 return ui::ResourceBundle::GetSharedInstance().GetFontList( |
| 743 GetTextStyle(text_type).font); | 748 GetTextStyle(text_type).font); |
| 744 } | 749 } |
| 745 | 750 |
| 746 int OmniboxResultView::GetAnswerHeight() const { | 751 int OmniboxResultView::GetAnswerHeight() const { |
| 747 // If the answer specifies a maximum of 1 line we can simply return the answer | 752 // If the answer specifies a maximum of 1 line we can simply return the answer |
| 748 // font height. | 753 // font height. |
| 749 if (match_.answer->second_line().num_text_lines() == 1) | 754 if (match_.answer->second_line().num_text_lines() == 1) |
| 750 return GetAnswerFont().GetHeight(); | 755 return GetAnswerFont().GetHeight() + kVerticalPadding; |
| 751 | 756 |
| 752 // Multi-line answers require layout in order to determine the number of lines | 757 // Multi-line answers require layout in order to determine the number of lines |
| 753 // the RenderText will use. | 758 // the RenderText will use. |
| 754 if (!description_rendertext_) { | 759 if (!description_rendertext_) { |
| 755 description_rendertext_ = | 760 description_rendertext_ = |
| 756 CreateAnswerText(match_.answer->second_line(), GetAnswerFont()); | 761 CreateAnswerText(match_.answer->second_line(), GetAnswerFont()); |
| 757 } | 762 } |
| 758 description_rendertext_->SetDisplayRect(gfx::Rect(text_bounds_.width(), 0)); | 763 description_rendertext_->SetDisplayRect(gfx::Rect(text_bounds_.width(), 0)); |
| 759 description_rendertext_->GetStringSize(); | 764 description_rendertext_->GetStringSize(); |
| 760 return GetAnswerFont().GetHeight() * description_rendertext_->GetNumLines(); | 765 return (GetAnswerFont().GetHeight() * |
| 766 description_rendertext_->GetNumLines()) + | |
| 767 kVerticalPadding; | |
| 761 } | 768 } |
| 762 | 769 |
| 763 int OmniboxResultView::GetVerticalMargin() const { | 770 int OmniboxResultView::GetVerticalMargin() const { |
| 764 // Regardless of the text size, we ensure a minimum size for the content line | 771 // Regardless of the text size, we ensure a minimum size for the content line |
| 765 // here. This minimum is larger for hybrid mouse/touch devices to ensure an | 772 // here. This minimum is larger for hybrid mouse/touch devices to ensure an |
| 766 // adequately sized touch target. | 773 // adequately sized touch target. |
| 767 using Md = ui::MaterialDesignController; | 774 using Md = ui::MaterialDesignController; |
| 768 const int kIconVerticalPad = base::GetFieldTrialParamByFeatureAsInt( | 775 const int kIconVerticalPad = base::GetFieldTrialParamByFeatureAsInt( |
| 769 omnibox::kUIExperimentVerticalMargin, | 776 omnibox::kUIExperimentVerticalMargin, |
| 770 OmniboxFieldTrial::kUIVerticalMarginParam, | 777 OmniboxFieldTrial::kUIVerticalMarginParam, |
| 771 Md::GetMode() == Md::MATERIAL_HYBRID ? 8 : 4); | 778 Md::GetMode() == Md::MATERIAL_HYBRID ? 8 : 4); |
| 772 const int min_height = LocationBarView::kIconWidth + 2 * kIconVerticalPad; | 779 const int min_height = LocationBarView::kIconWidth + 2 * kIconVerticalPad; |
| 773 | 780 |
| 774 return std::max(kVerticalPadding, (min_height - GetTextHeight()) / 2); | 781 return std::max(kVerticalMargin, (min_height - GetTextHeight()) / 2); |
| 775 } | 782 } |
| 776 | 783 |
| 777 std::unique_ptr<gfx::RenderText> OmniboxResultView::CreateAnswerText( | 784 std::unique_ptr<gfx::RenderText> OmniboxResultView::CreateAnswerText( |
| 778 const SuggestionAnswer::ImageLine& line, | 785 const SuggestionAnswer::ImageLine& line, |
| 779 const gfx::FontList& font_list) const { | 786 const gfx::FontList& font_list) const { |
| 780 std::unique_ptr<gfx::RenderText> destination = | 787 std::unique_ptr<gfx::RenderText> destination = |
| 781 CreateRenderText(base::string16()); | 788 CreateRenderText(base::string16()); |
| 782 destination->SetFontList(font_list); | 789 destination->SetFontList(font_list); |
| 783 | 790 |
| 784 for (const SuggestionAnswer::TextField& text_field : line.text_fields()) | 791 for (const SuggestionAnswer::TextField& text_field : line.text_fields()) |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 846 destination->AppendText(text); | 853 destination->AppendText(text); |
| 847 const TextStyle& text_style = GetTextStyle(text_type); | 854 const TextStyle& text_style = GetTextStyle(text_type); |
| 848 // TODO(dschuyler): follow up on the problem of different font sizes within | 855 // TODO(dschuyler): follow up on the problem of different font sizes within |
| 849 // one RenderText. Maybe with destination->SetFontList(...). | 856 // one RenderText. Maybe with destination->SetFontList(...). |
| 850 destination->ApplyWeight( | 857 destination->ApplyWeight( |
| 851 is_bold ? gfx::Font::Weight::BOLD : gfx::Font::Weight::NORMAL, range); | 858 is_bold ? gfx::Font::Weight::BOLD : gfx::Font::Weight::NORMAL, range); |
| 852 destination->ApplyColor( | 859 destination->ApplyColor( |
| 853 GetNativeTheme()->GetSystemColor(text_style.colors[GetState()]), range); | 860 GetNativeTheme()->GetSystemColor(text_style.colors[GetState()]), range); |
| 854 destination->ApplyBaselineStyle(text_style.baseline, range); | 861 destination->ApplyBaselineStyle(text_style.baseline, range); |
| 855 } | 862 } |
| OLD | NEW |