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 #include "chrome/browser/ui/views/autocomplete/touch_autocomplete_popup_contents _view.h" | 5 #include "chrome/browser/ui/views/autocomplete/touch_autocomplete_popup_contents _view.h" |
| 6 | 6 |
| 7 #include "chrome/browser/ui/omnibox/omnibox_view.h" | 7 #include "chrome/browser/ui/omnibox/omnibox_view.h" |
| 8 #include "third_party/skia/include/core/SkPaint.h" | 8 #include "third_party/skia/include/core/SkPaint.h" |
| 9 #include "ui/gfx/canvas.h" | 9 #include "ui/gfx/canvas.h" |
| 10 #include "ui/gfx/font.h" | 10 #include "ui/gfx/font.h" |
| 11 #include "ui/gfx/path.h" | 11 #include "ui/gfx/path.h" |
| 12 #include "ui/gfx/rect.h" | 12 #include "ui/gfx/rect.h" |
| 13 #include "ui/gfx/size.h" | 13 #include "ui/gfx/size.h" |
| 14 #include "ui/views/view.h" | 14 #include "ui/views/view.h" |
| 15 | 15 |
| 16 namespace { | |
| 17 | |
| 18 // Colors for a light-gray 3D-looking divider made up of two lines. | |
|
Peter Kasting
2012/05/04 23:33:31
It's not safe to use hardcoded colors because ever
Jói
2012/05/04 23:52:19
Good point, will look into using the system colors
Jói
2012/05/07 16:26:18
I've switched to using system colors, am waiting t
| |
| 19 const SkColor kDividerLineTopColor = | |
| 20 SkColorSetARGBMacro(0xff, 0xe3, 0xe3, 0xe3); | |
| 21 const SkColor kDividerLineBottomColor = | |
| 22 SkColorSetARGBMacro(0xff, 0xfe, 0xfe, 0xfe); | |
| 23 | |
| 24 } // namespace | |
| 25 | |
| 16 | 26 |
| 17 // TouchAutocompleteResultView ------------------------------------------------ | 27 // TouchAutocompleteResultView ------------------------------------------------ |
| 18 | 28 |
| 19 TouchAutocompleteResultView::TouchAutocompleteResultView( | 29 TouchAutocompleteResultView::TouchAutocompleteResultView( |
| 20 AutocompleteResultViewModel* model, | 30 AutocompleteResultViewModel* model, |
| 21 int model_index, | 31 int model_index, |
| 22 const gfx::Font& font, | 32 const gfx::Font& font, |
| 23 const gfx::Font& bold_font) | 33 const gfx::Font& bold_font) |
| 24 : AutocompleteResultView(model, model_index, font, bold_font) { | 34 : AutocompleteResultView(model, model_index, font, bold_font) { |
| 35 edge_item_padding_ *= 3; | |
| 36 item_padding_ *= 3; | |
| 37 minimum_text_vertical_padding_ = 10; | |
| 25 } | 38 } |
| 26 | 39 |
| 27 TouchAutocompleteResultView::~TouchAutocompleteResultView() { | 40 TouchAutocompleteResultView::~TouchAutocompleteResultView() { |
| 28 } | 41 } |
| 29 | 42 |
| 30 void TouchAutocompleteResultView::PaintMatch(gfx::Canvas* canvas, | 43 void TouchAutocompleteResultView::PaintMatch(gfx::Canvas* canvas, |
| 31 const AutocompleteMatch& match, | 44 const AutocompleteMatch& match, |
| 32 int x) { | 45 int x) { |
| 33 DrawString(canvas, match.contents, match.contents_class, false, x, | 46 bool description = !match.description.empty(); |
| 34 text_bounds().y()); | 47 int y = text_bounds().y(); |
| 35 | 48 |
| 36 if (!match.description.empty()) { | 49 // When we have only one line of content (no description), we center the |
| 50 // single line vertically on our two-lines-tall results box. | |
| 51 if (!description) | |
|
Peter Kasting
2012/05/04 23:33:31
Nit: if (match.description.empty()) { ... } else {
Jói
2012/05/07 16:26:18
Done.
| |
| 52 y += AutocompleteResultView::GetTextHeight() / 2; | |
| 53 | |
| 54 if (description) { | |
| 37 // We use our base class's GetTextHeight below because we need the height | 55 // We use our base class's GetTextHeight below because we need the height |
| 38 // of a single line of text. | 56 // of a single line of text. |
| 39 DrawString(canvas, match.description, match.description_class, true, x, | 57 DrawString(canvas, match.description, match.description_class, true, x, y); |
| 40 text_bounds().y() + AutocompleteResultView::GetTextHeight()); | 58 y += AutocompleteResultView::GetTextHeight(); |
| 41 } | 59 } |
| 60 | |
| 61 DrawString(canvas, match.contents, match.contents_class, false, x, y); | |
| 42 } | 62 } |
| 43 | 63 |
| 44 int TouchAutocompleteResultView::GetTextHeight() const { | 64 int TouchAutocompleteResultView::GetTextHeight() const { |
| 45 // In the touch version of the autocomplete popup, the text is displayed in | |
| 46 // two lines: First line is the title of the suggestion and second is the | |
| 47 // description. Hence, the total text height is twice the height of one line. | |
| 48 return AutocompleteResultView::GetTextHeight() * 2; | 65 return AutocompleteResultView::GetTextHeight() * 2; |
| 49 } | 66 } |
| 50 | 67 |
| 68 void TouchAutocompleteResultView::AdjustIconBounds( | |
| 69 const AutocompleteMatch& match, gfx::Rect* bounds) { | |
| 70 // We show the icon centered on the first line of content, so we | |
| 71 // need to adjust the bounds when there are two lines. | |
|
Peter Kasting
2012/05/04 23:33:31
Don't we need to do this all the time, not just wh
Jói
2012/05/04 23:52:19
The default case is that it's centered on the whol
Jói
2012/05/07 16:26:18
Added to the comment to explain why we don't need
| |
| 72 if (!match.description.empty()) { | |
| 73 bounds->set_y((AutocompleteResultView::GetTextHeight() - bounds->height()) / | |
| 74 2 + minimum_text_vertical_padding_); | |
|
Peter Kasting
2012/05/04 23:33:31
Nit: The linebreak makes it look as if you're divi
Jói
2012/05/07 16:26:18
Done.
| |
| 75 } | |
| 76 } | |
| 77 | |
| 51 | 78 |
| 52 // TouchAutocompletePopupContentsView ----------------------------------------- | 79 // TouchAutocompletePopupContentsView ----------------------------------------- |
| 53 | 80 |
| 54 TouchAutocompletePopupContentsView::TouchAutocompletePopupContentsView( | 81 TouchAutocompletePopupContentsView::TouchAutocompletePopupContentsView( |
| 55 const gfx::Font& font, | 82 const gfx::Font& font, |
| 56 OmniboxView* omnibox_view, | 83 OmniboxView* omnibox_view, |
| 57 AutocompleteEditModel* edit_model, | 84 AutocompleteEditModel* edit_model, |
| 58 views::View* location_bar) | 85 views::View* location_bar) |
| 59 : AutocompletePopupContentsView(font, omnibox_view, edit_model, | 86 : AutocompletePopupContentsView(font, omnibox_view, edit_model, |
| 60 location_bar) { | 87 location_bar) { |
| 61 } | 88 } |
| 62 | 89 |
| 63 TouchAutocompletePopupContentsView::~TouchAutocompletePopupContentsView() { | 90 TouchAutocompletePopupContentsView::~TouchAutocompletePopupContentsView() { |
| 64 } | 91 } |
| 65 | 92 |
| 66 void TouchAutocompletePopupContentsView::UpdatePopupAppearance() { | 93 void TouchAutocompletePopupContentsView::UpdatePopupAppearance() { |
| 67 AutocompletePopupContentsView::UpdatePopupAppearance(); | 94 AutocompletePopupContentsView::UpdatePopupAppearance(); |
| 68 Layout(); | 95 Layout(); |
| 69 } | 96 } |
| 70 | 97 |
| 71 void TouchAutocompletePopupContentsView::LayoutChildren() { | |
| 72 std::vector<View*> visible_children(GetVisibleChildren()); | |
| 73 gfx::Rect bounds(GetContentsBounds()); | |
| 74 double child_width = | |
| 75 static_cast<double>(bounds.width()) / visible_children.size(); | |
| 76 int x = bounds.x(); | |
| 77 for (size_t i = 0; i < visible_children.size(); ++i) { | |
| 78 int next_x = bounds.x() + static_cast<int>(((i + 1) * child_width) + 0.5); | |
| 79 visible_children[i]->SetBounds(x, bounds.y(), next_x - x, bounds.height()); | |
| 80 x = next_x; | |
| 81 } | |
| 82 } | |
| 83 | |
| 84 void TouchAutocompletePopupContentsView::PaintResultViews(gfx::Canvas* canvas) { | 98 void TouchAutocompletePopupContentsView::PaintResultViews(gfx::Canvas* canvas) { |
| 85 AutocompletePopupContentsView::PaintResultViews(canvas); | 99 AutocompletePopupContentsView::PaintResultViews(canvas); |
| 86 | 100 |
| 87 // Draw divider lines. | 101 // Draw divider lines. |
| 88 std::vector<View*> visible_children(GetVisibleChildren()); | 102 std::vector<View*> visible_children(GetVisibleChildren()); |
| 89 if (visible_children.size() < 2) | 103 if (visible_children.size() < 2) |
| 90 return; | 104 return; |
| 91 SkColor color = AutocompleteResultView::GetColor( | |
| 92 AutocompleteResultView::NORMAL, AutocompleteResultView::DIMMED_TEXT); | |
| 93 gfx::Rect bounds(GetContentsBounds()); | 105 gfx::Rect bounds(GetContentsBounds()); |
| 94 for (std::vector<View*>::const_iterator i(visible_children.begin() + 1); | 106 for (std::vector<View*>::const_iterator i(visible_children.begin() + 1); |
| 95 i != visible_children.end(); ++i) { | 107 i != visible_children.end(); ++i) { |
| 96 canvas->DrawLine(gfx::Point((*i)->x(), bounds.y()), | 108 TouchAutocompleteResultView* child = |
| 97 gfx::Point((*i)->x(), bounds.bottom()), color); | 109 static_cast<TouchAutocompleteResultView*>(*i); |
| 110 canvas->DrawLine( | |
| 111 gfx::Point(bounds.x(), child->y() - 1), | |
| 112 gfx::Point(bounds.right(), child->y() - 1), | |
| 113 kDividerLineTopColor); | |
| 114 if (child->GetState() == AutocompleteResultView::NORMAL) { | |
| 115 canvas->DrawLine( | |
| 116 gfx::Point(bounds.x(), child->y()), | |
| 117 gfx::Point(bounds.right(), child->y()), | |
| 118 kDividerLineBottomColor); | |
| 119 } | |
| 98 } | 120 } |
| 99 } | 121 } |
| 100 | 122 |
| 101 int TouchAutocompletePopupContentsView::CalculatePopupHeight() { | |
| 102 DCHECK_GE(static_cast<size_t>(child_count()), model_->result().size()); | |
| 103 int popup_height = 0; | |
| 104 for (size_t i = 0; i < model_->result().size(); ++i) { | |
| 105 popup_height = std::max(popup_height, | |
| 106 child_at(i)->GetPreferredSize().height()); | |
| 107 } | |
| 108 return popup_height; | |
| 109 } | |
| 110 | |
| 111 AutocompleteResultView* TouchAutocompletePopupContentsView::CreateResultView( | 123 AutocompleteResultView* TouchAutocompletePopupContentsView::CreateResultView( |
| 112 AutocompleteResultViewModel* model, | 124 AutocompleteResultViewModel* model, |
| 113 int model_index, | 125 int model_index, |
| 114 const gfx::Font& font, | 126 const gfx::Font& font, |
| 115 const gfx::Font& bold_font) { | 127 const gfx::Font& bold_font) { |
| 116 return new TouchAutocompleteResultView(model, model_index, font, bold_font); | 128 return new TouchAutocompleteResultView(model, model_index, font, bold_font); |
| 117 } | 129 } |
| 118 | 130 |
| 119 std::vector<views::View*> | 131 std::vector<views::View*> |
| 120 TouchAutocompletePopupContentsView::GetVisibleChildren() { | 132 TouchAutocompletePopupContentsView::GetVisibleChildren() { |
| 121 std::vector<View*> visible_children; | 133 std::vector<View*> visible_children; |
| 122 for (int i = 0; i < child_count(); ++i) { | 134 for (int i = 0; i < child_count(); ++i) { |
| 123 View* v = child_at(i); | 135 View* v = child_at(i); |
| 124 if (child_at(i)->visible()) | 136 if (child_at(i)->visible()) |
| 125 visible_children.push_back(v); | 137 visible_children.push_back(v); |
| 126 } | 138 } |
| 127 return visible_children; | 139 return visible_children; |
| 128 } | 140 } |
| OLD | NEW |