Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: chrome/browser/ui/views/omnibox/omnibox_result_view.cc

Issue 2936533004: Provide vertical padding to the RenderTexts used in suggestions. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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;
Peter Kasting 2017/06/13 23:42:50 So why a margin of 1 and padding of 4 instead of a
Justin Donnelly 2017/06/15 18:56:53 Because that won't work in the multi-part case (an
Peter Kasting 2017/06/15 22:43:34 OK, but using 1 and 4 is sufficient for your needs
Justin Donnelly 2017/06/16 14:14:30 Yes. I've tested this extensively on Linux and Win
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;
Peter Kasting 2017/06/13 23:42:50 Nit: kAdditionalTextLineHeight? Should this just
Justin Donnelly 2017/06/15 18:56:53 That would add additional, undesired space between
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
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
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 = GetAnswerHeight();
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), y,
375 answer_icon_size, answer_icon_size, true); 379 answer_icon_size, answer_icon_size, true);
376 // TODO(dschuyler): Perhaps this should be based on the font size 380 // 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 381 // 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 382 // appropriate font to the beginning of the description, then reducing
379 // the additional padding here to zero). 383 // the additional padding here to zero).
380 const int kAnswerIconToTextPadding = 2; 384 const int kAnswerIconToTextPadding = 2;
381 x += answer_icon_size + kAnswerIconToTextPadding; 385 x += answer_icon_size + kAnswerIconToTextPadding;
382 } 386 }
383 DrawRenderText(match, description, DESCRIPTION, canvas, x, y, 387 DrawRenderText(match, description, DESCRIPTION, canvas, x, y,
384 description_max_width); 388 description_max_width);
385 return; 389 return;
386 } 390 }
387 391
388 // Regular results. 392 // Regular results.
389 if (base::FeatureList::IsEnabled(omnibox::kUIExperimentVerticalLayout)) { 393 if (base::FeatureList::IsEnabled(omnibox::kUIExperimentVerticalLayout)) {
390 // For no description, shift down halfways to draw contents in middle. 394 // For no description, shift down halfways to draw contents in middle.
391 if (description_max_width == 0) 395 if (description_max_width == 0)
392 y += (GetTextHeight() + kVerticalPadding) / 2; 396 y += GetTextHeight() / 2;
393 397
394 DrawRenderText(match, contents, CONTENTS, canvas, x, y, contents_max_width); 398 DrawRenderText(match, contents, CONTENTS, canvas, x, y, contents_max_width);
395 399
396 if (description_max_width != 0) { 400 if (description_max_width != 0) {
397 y += GetTextHeight() + kVerticalPadding; 401 y += GetTextHeight();
398 DrawRenderText(match, description, DESCRIPTION, canvas, x, y, 402 DrawRenderText(match, description, DESCRIPTION, canvas, x, y,
399 description_max_width); 403 description_max_width);
400 } 404 }
401 } else { 405 } else {
402 x = DrawRenderText(match, contents, CONTENTS, canvas, x, y, 406 x = DrawRenderText(match, contents, CONTENTS, canvas, x, y,
403 contents_max_width); 407 contents_max_width);
404 if (description_max_width != 0) { 408 if (description_max_width != 0) {
405 x = DrawRenderText(match, separator_rendertext_.get(), SEPARATOR, canvas, 409 x = DrawRenderText(match, separator_rendertext_.get(), SEPARATOR, canvas,
406 x, y, separator_width_); 410 x, y, separator_width_);
407 DrawRenderText(match, description, DESCRIPTION, canvas, x, y, 411 DrawRenderText(match, description, DESCRIPTION, canvas, x, y,
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 // the omnibox border outline shape exactly in OnPaint(). We have to inset 644 // the omnibox border outline shape exactly in OnPaint(). We have to inset
641 // here to keep the icons lined up. 645 // here to keep the icons lined up.
642 const int start_x = BackgroundWith1PxBorder::kLocationBarBorderThicknessDip + 646 const int start_x = BackgroundWith1PxBorder::kLocationBarBorderThicknessDip +
643 horizontal_padding; 647 horizontal_padding;
644 const int end_x = width() - start_x; 648 const int end_x = width() - start_x;
645 649
646 const gfx::ImageSkia icon = GetIcon(); 650 const gfx::ImageSkia icon = GetIcon();
647 651
648 int row_height = GetTextHeight(); 652 int row_height = GetTextHeight();
649 if (base::FeatureList::IsEnabled(omnibox::kUIExperimentVerticalLayout)) 653 if (base::FeatureList::IsEnabled(omnibox::kUIExperimentVerticalLayout))
650 row_height += kVerticalPadding + GetTextHeight(); 654 row_height += match_.answer ? GetTextHeight() : GetAnswerHeight();
651 655
652 const int icon_y = GetVerticalMargin() + (row_height - icon.height()) / 2; 656 const int icon_y = GetVerticalMargin() + (row_height - icon.height()) / 2;
653 icon_bounds_.SetRect(start_x, icon_y, icon.width(), icon.height()); 657 icon_bounds_.SetRect(start_x, icon_y, icon.width(), icon.height());
654 658
655 const int text_x = start_x + LocationBarView::kIconWidth + horizontal_padding; 659 const int text_x = start_x + LocationBarView::kIconWidth + horizontal_padding;
656 int text_width = end_x - text_x; 660 int text_width = end_x - text_x;
657 661
658 if (match_.associated_keyword.get()) { 662 if (match_.associated_keyword.get()) {
659 const int max_kw_x = end_x - keyword_icon_->width(); 663 const int max_kw_x = end_x - keyword_icon_->width();
660 const int kw_x = animation_->CurrentValueBetween(max_kw_x, start_x); 664 const int kw_x = animation_->CurrentValueBetween(max_kw_x, start_x);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 ? match_.answer->second_line().text_fields()[0].type() 744 ? match_.answer->second_line().text_fields()[0].type()
741 : SuggestionAnswer::SUGGESTION; 745 : SuggestionAnswer::SUGGESTION;
742 return ui::ResourceBundle::GetSharedInstance().GetFontList( 746 return ui::ResourceBundle::GetSharedInstance().GetFontList(
743 GetTextStyle(text_type).font); 747 GetTextStyle(text_type).font);
744 } 748 }
745 749
746 int OmniboxResultView::GetAnswerHeight() const { 750 int OmniboxResultView::GetAnswerHeight() const {
747 // If the answer specifies a maximum of 1 line we can simply return the answer 751 // If the answer specifies a maximum of 1 line we can simply return the answer
748 // font height. 752 // font height.
749 if (match_.answer->second_line().num_text_lines() == 1) 753 if (match_.answer->second_line().num_text_lines() == 1)
750 return GetAnswerFont().GetHeight(); 754 return GetAnswerFont().GetHeight() + kVerticalPadding;
751 755
752 // Multi-line answers require layout in order to determine the number of lines 756 // Multi-line answers require layout in order to determine the number of lines
753 // the RenderText will use. 757 // the RenderText will use.
754 if (!description_rendertext_) { 758 if (!description_rendertext_) {
755 description_rendertext_ = 759 description_rendertext_ =
756 CreateAnswerText(match_.answer->second_line(), GetAnswerFont()); 760 CreateAnswerText(match_.answer->second_line(), GetAnswerFont());
757 } 761 }
758 description_rendertext_->SetDisplayRect(gfx::Rect(text_bounds_.width(), 0)); 762 description_rendertext_->SetDisplayRect(gfx::Rect(text_bounds_.width(), 0));
759 description_rendertext_->GetStringSize(); 763 description_rendertext_->GetStringSize();
760 return GetAnswerFont().GetHeight() * description_rendertext_->GetNumLines(); 764 return (GetAnswerFont().GetHeight() *
765 description_rendertext_->GetNumLines()) +
766 kVerticalPadding;
761 } 767 }
762 768
763 int OmniboxResultView::GetVerticalMargin() const { 769 int OmniboxResultView::GetVerticalMargin() const {
764 // Regardless of the text size, we ensure a minimum size for the content line 770 // 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 771 // here. This minimum is larger for hybrid mouse/touch devices to ensure an
766 // adequately sized touch target. 772 // adequately sized touch target.
767 using Md = ui::MaterialDesignController; 773 using Md = ui::MaterialDesignController;
768 const int kIconVerticalPad = base::GetFieldTrialParamByFeatureAsInt( 774 const int kIconVerticalPad = base::GetFieldTrialParamByFeatureAsInt(
769 omnibox::kUIExperimentVerticalMargin, 775 omnibox::kUIExperimentVerticalMargin,
770 OmniboxFieldTrial::kUIVerticalMarginParam, 776 OmniboxFieldTrial::kUIVerticalMarginParam,
771 Md::GetMode() == Md::MATERIAL_HYBRID ? 8 : 4); 777 Md::GetMode() == Md::MATERIAL_HYBRID ? 8 : 4);
772 const int min_height = LocationBarView::kIconWidth + 2 * kIconVerticalPad; 778 const int min_height = LocationBarView::kIconWidth + 2 * kIconVerticalPad;
773 779
774 return std::max(kVerticalPadding, (min_height - GetTextHeight()) / 2); 780 return std::max(kVerticalMargin, (min_height - GetTextHeight()) / 2);
775 } 781 }
776 782
777 std::unique_ptr<gfx::RenderText> OmniboxResultView::CreateAnswerText( 783 std::unique_ptr<gfx::RenderText> OmniboxResultView::CreateAnswerText(
778 const SuggestionAnswer::ImageLine& line, 784 const SuggestionAnswer::ImageLine& line,
779 const gfx::FontList& font_list) const { 785 const gfx::FontList& font_list) const {
780 std::unique_ptr<gfx::RenderText> destination = 786 std::unique_ptr<gfx::RenderText> destination =
781 CreateRenderText(base::string16()); 787 CreateRenderText(base::string16());
782 destination->SetFontList(font_list); 788 destination->SetFontList(font_list);
783 789
784 for (const SuggestionAnswer::TextField& text_field : line.text_fields()) 790 for (const SuggestionAnswer::TextField& text_field : line.text_fields())
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 destination->AppendText(text); 852 destination->AppendText(text);
847 const TextStyle& text_style = GetTextStyle(text_type); 853 const TextStyle& text_style = GetTextStyle(text_type);
848 // TODO(dschuyler): follow up on the problem of different font sizes within 854 // TODO(dschuyler): follow up on the problem of different font sizes within
849 // one RenderText. Maybe with destination->SetFontList(...). 855 // one RenderText. Maybe with destination->SetFontList(...).
850 destination->ApplyWeight( 856 destination->ApplyWeight(
851 is_bold ? gfx::Font::Weight::BOLD : gfx::Font::Weight::NORMAL, range); 857 is_bold ? gfx::Font::Weight::BOLD : gfx::Font::Weight::NORMAL, range);
852 destination->ApplyColor( 858 destination->ApplyColor(
853 GetNativeTheme()->GetSystemColor(text_style.colors[GetState()]), range); 859 GetNativeTheme()->GetSystemColor(text_style.colors[GetState()]), range);
854 destination->ApplyBaselineStyle(text_style.baseline, range); 860 destination->ApplyBaselineStyle(text_style.baseline, range);
855 } 861 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698