| 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 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <atlbase.h> // NOLINT | 8 #include <atlbase.h> // NOLINT |
| 9 #include <atlwin.h> // NOLINT | 9 #include <atlwin.h> // NOLINT |
| 10 #endif | 10 #endif |
| 11 | 11 |
| 12 #include "chrome/browser/ui/views/autocomplete/autocomplete_result_view.h" | 12 #include "chrome/browser/ui/views/omnibox/omnibox_result_view.h" |
| 13 | 13 |
| 14 #include <algorithm> // NOLINT | 14 #include <algorithm> // NOLINT |
| 15 | 15 |
| 16 #include "base/i18n/bidi_line_iterator.h" | 16 #include "base/i18n/bidi_line_iterator.h" |
| 17 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" | 17 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" |
| 18 #include "chrome/browser/ui/views/autocomplete/autocomplete_result_view_model.h" | |
| 19 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" | 18 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" |
| 19 #include "chrome/browser/ui/views/omnibox/omnibox_result_view_model.h" |
| 20 #include "grit/generated_resources.h" | 20 #include "grit/generated_resources.h" |
| 21 #include "grit/theme_resources.h" | 21 #include "grit/theme_resources.h" |
| 22 #include "ui/base/l10n/l10n_util.h" | 22 #include "ui/base/l10n/l10n_util.h" |
| 23 #include "ui/base/native_theme/native_theme.h" | 23 #include "ui/base/native_theme/native_theme.h" |
| 24 #include "ui/base/resource/resource_bundle.h" | 24 #include "ui/base/resource/resource_bundle.h" |
| 25 #include "ui/base/text/text_elider.h" | 25 #include "ui/base/text/text_elider.h" |
| 26 #include "ui/gfx/canvas.h" | 26 #include "ui/gfx/canvas.h" |
| 27 #include "ui/gfx/color_utils.h" | 27 #include "ui/gfx/color_utils.h" |
| 28 | 28 |
| 29 namespace { | 29 namespace { |
| 30 | 30 |
| 31 const char16 kEllipsis[] = { 0x2026, 0x0 }; | 31 const char16 kEllipsis[] = { 0x2026, 0x0 }; |
| 32 | 32 |
| 33 // The minimum distance between the top and bottom of the {icon|text} and the | 33 // The minimum distance between the top and bottom of the {icon|text} and the |
| 34 // top or bottom of the row. | 34 // top or bottom of the row. |
| 35 const int kMinimumIconVerticalPadding = 2; | 35 const int kMinimumIconVerticalPadding = 2; |
| 36 const int kMinimumTextVerticalPadding = 3; | 36 const int kMinimumTextVerticalPadding = 3; |
| 37 | 37 |
| 38 } // namespace | 38 } // namespace |
| 39 | 39 |
| 40 //////////////////////////////////////////////////////////////////////////////// | 40 //////////////////////////////////////////////////////////////////////////////// |
| 41 // AutocompleteResultView, public: | 41 // OmniboxResultView, public: |
| 42 | 42 |
| 43 // Precalculated data used to draw the portion of a match classification that | 43 // Precalculated data used to draw the portion of a match classification that |
| 44 // fits entirely within one run. | 44 // fits entirely within one run. |
| 45 struct AutocompleteResultView::ClassificationData { | 45 struct OmniboxResultView::ClassificationData { |
| 46 string16 text; | 46 string16 text; |
| 47 const gfx::Font* font; | 47 const gfx::Font* font; |
| 48 SkColor color; | 48 SkColor color; |
| 49 gfx::Size pixel_size; | 49 gfx::Size pixel_size; |
| 50 }; | 50 }; |
| 51 | 51 |
| 52 // Precalculated data used to draw a complete visual run within the match. | 52 // Precalculated data used to draw a complete visual run within the match. |
| 53 // This will include all or part of at leasdt one, and possibly several, | 53 // This will include all or part of at leasdt one, and possibly several, |
| 54 // classifications. | 54 // classifications. |
| 55 struct AutocompleteResultView::RunData { | 55 struct OmniboxResultView::RunData { |
| 56 size_t run_start; // Offset within the match text where this run begins. | 56 size_t run_start; // Offset within the match text where this run begins. |
| 57 int visual_order; // Where this run occurs in visual order. The earliest | 57 int visual_order; // Where this run occurs in visual order. The earliest |
| 58 // run drawn is run 0. | 58 // run drawn is run 0. |
| 59 bool is_rtl; | 59 bool is_rtl; |
| 60 int pixel_width; | 60 int pixel_width; |
| 61 Classifications classifications; // Classification pieces within this run, | 61 Classifications classifications; // Classification pieces within this run, |
| 62 // in logical order. | 62 // in logical order. |
| 63 }; | 63 }; |
| 64 | 64 |
| 65 // This class is a utility class for calculations affected by whether the result | 65 // This class is a utility class for calculations affected by whether the result |
| 66 // view is horizontally mirrored. The drawing functions can be written as if | 66 // view is horizontally mirrored. The drawing functions can be written as if |
| 67 // all drawing occurs left-to-right, and then use this class to get the actual | 67 // all drawing occurs left-to-right, and then use this class to get the actual |
| 68 // coordinates to begin drawing onscreen. | 68 // coordinates to begin drawing onscreen. |
| 69 class AutocompleteResultView::MirroringContext { | 69 class OmniboxResultView::MirroringContext { |
| 70 public: | 70 public: |
| 71 MirroringContext() : center_(0), right_(0) {} | 71 MirroringContext() : center_(0), right_(0) {} |
| 72 | 72 |
| 73 // Tells the mirroring context to use the provided range as the physical | 73 // Tells the mirroring context to use the provided range as the physical |
| 74 // bounds of the drawing region. When coordinate mirroring is needed, the | 74 // bounds of the drawing region. When coordinate mirroring is needed, the |
| 75 // mirror point will be the center of this range. | 75 // mirror point will be the center of this range. |
| 76 void Initialize(int x, int width) { | 76 void Initialize(int x, int width) { |
| 77 center_ = x + width / 2; | 77 center_ = x + width / 2; |
| 78 right_ = x + width; | 78 right_ = x + width; |
| 79 } | 79 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 91 return right_ - x; | 91 return right_ - x; |
| 92 } | 92 } |
| 93 | 93 |
| 94 private: | 94 private: |
| 95 int center_; | 95 int center_; |
| 96 int right_; | 96 int right_; |
| 97 | 97 |
| 98 DISALLOW_COPY_AND_ASSIGN(MirroringContext); | 98 DISALLOW_COPY_AND_ASSIGN(MirroringContext); |
| 99 }; | 99 }; |
| 100 | 100 |
| 101 AutocompleteResultView::AutocompleteResultView( | 101 OmniboxResultView::OmniboxResultView( |
| 102 AutocompleteResultViewModel* model, | 102 OmniboxResultViewModel* model, |
| 103 int model_index, | 103 int model_index, |
| 104 const gfx::Font& font, | 104 const gfx::Font& font, |
| 105 const gfx::Font& bold_font) | 105 const gfx::Font& bold_font) |
| 106 : edge_item_padding_(LocationBarView::GetItemPadding()), | 106 : edge_item_padding_(LocationBarView::GetItemPadding()), |
| 107 item_padding_(LocationBarView::GetItemPadding()), | 107 item_padding_(LocationBarView::GetItemPadding()), |
| 108 minimum_text_vertical_padding_(kMinimumTextVerticalPadding), | 108 minimum_text_vertical_padding_(kMinimumTextVerticalPadding), |
| 109 model_(model), | 109 model_(model), |
| 110 model_index_(model_index), | 110 model_index_(model_index), |
| 111 normal_font_(font), | 111 normal_font_(font), |
| 112 bold_font_(bold_font), | 112 bold_font_(bold_font), |
| 113 ellipsis_width_(font.GetStringWidth(string16(kEllipsis))), | 113 ellipsis_width_(font.GetStringWidth(string16(kEllipsis))), |
| 114 mirroring_context_(new MirroringContext()), | 114 mirroring_context_(new MirroringContext()), |
| 115 keyword_icon_(new views::ImageView()), | 115 keyword_icon_(new views::ImageView()), |
| 116 ALLOW_THIS_IN_INITIALIZER_LIST( | 116 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 117 animation_(new ui::SlideAnimation(this))) { | 117 animation_(new ui::SlideAnimation(this))) { |
| 118 CHECK_GE(model_index, 0); | 118 CHECK_GE(model_index, 0); |
| 119 if (default_icon_size_ == 0) { | 119 if (default_icon_size_ == 0) { |
| 120 default_icon_size_ = | 120 default_icon_size_ = |
| 121 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | 121 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
| 122 AutocompleteMatch::TypeToIcon(AutocompleteMatch::URL_WHAT_YOU_TYPED))-> | 122 AutocompleteMatch::TypeToIcon(AutocompleteMatch::URL_WHAT_YOU_TYPED))-> |
| 123 width(); | 123 width(); |
| 124 } | 124 } |
| 125 keyword_icon_->set_owned_by_client(); | 125 keyword_icon_->set_owned_by_client(); |
| 126 keyword_icon_->EnableCanvasFlippingForRTLUI(true); | 126 keyword_icon_->EnableCanvasFlippingForRTLUI(true); |
| 127 keyword_icon_->SetImage(GetKeywordIcon()); | 127 keyword_icon_->SetImage(GetKeywordIcon()); |
| 128 keyword_icon_->SizeToPreferredSize(); | 128 keyword_icon_->SizeToPreferredSize(); |
| 129 } | 129 } |
| 130 | 130 |
| 131 AutocompleteResultView::~AutocompleteResultView() { | 131 OmniboxResultView::~OmniboxResultView() { |
| 132 } | 132 } |
| 133 | 133 |
| 134 // static | 134 // static |
| 135 SkColor AutocompleteResultView::GetColor(ResultViewState state, | 135 SkColor OmniboxResultView::GetColor(ResultViewState state, ColorKind kind) { |
| 136 ColorKind kind) { | |
| 137 static bool initialized = false; | 136 static bool initialized = false; |
| 138 static SkColor colors[NUM_STATES][NUM_KINDS]; | 137 static SkColor colors[NUM_STATES][NUM_KINDS]; |
| 139 if (!initialized) { | 138 if (!initialized) { |
| 140 #if defined(OS_WIN) | 139 #if defined(OS_WIN) |
| 141 colors[NORMAL][BACKGROUND] = color_utils::GetSysSkColor(COLOR_WINDOW); | 140 colors[NORMAL][BACKGROUND] = color_utils::GetSysSkColor(COLOR_WINDOW); |
| 142 colors[SELECTED][BACKGROUND] = color_utils::GetSysSkColor(COLOR_HIGHLIGHT); | 141 colors[SELECTED][BACKGROUND] = color_utils::GetSysSkColor(COLOR_HIGHLIGHT); |
| 143 colors[NORMAL][TEXT] = color_utils::GetSysSkColor(COLOR_WINDOWTEXT); | 142 colors[NORMAL][TEXT] = color_utils::GetSysSkColor(COLOR_WINDOWTEXT); |
| 144 colors[SELECTED][TEXT] = color_utils::GetSysSkColor(COLOR_HIGHLIGHTTEXT); | 143 colors[SELECTED][TEXT] = color_utils::GetSysSkColor(COLOR_HIGHLIGHTTEXT); |
| 145 #elif defined(USE_AURA) | 144 #elif defined(USE_AURA) |
| 146 const ui::NativeTheme* theme = ui::NativeTheme::instance(); | 145 const ui::NativeTheme* theme = ui::NativeTheme::instance(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 // alpha.) | 179 // alpha.) |
| 181 colors[i][DIVIDER] = | 180 colors[i][DIVIDER] = |
| 182 color_utils::AlphaBlend(colors[i][TEXT], colors[i][BACKGROUND], 0x34); | 181 color_utils::AlphaBlend(colors[i][TEXT], colors[i][BACKGROUND], 0x34); |
| 183 } | 182 } |
| 184 initialized = true; | 183 initialized = true; |
| 185 } | 184 } |
| 186 | 185 |
| 187 return colors[state][kind]; | 186 return colors[state][kind]; |
| 188 } | 187 } |
| 189 | 188 |
| 190 void AutocompleteResultView::SetMatch(const AutocompleteMatch& match) { | 189 void OmniboxResultView::SetMatch(const AutocompleteMatch& match) { |
| 191 match_ = match; | 190 match_ = match; |
| 192 animation_->Reset(); | 191 animation_->Reset(); |
| 193 | 192 |
| 194 if (match.associated_keyword.get()) { | 193 if (match.associated_keyword.get()) { |
| 195 keyword_icon_->SetImage(GetKeywordIcon()); | 194 keyword_icon_->SetImage(GetKeywordIcon()); |
| 196 | 195 |
| 197 if (!keyword_icon_->parent()) | 196 if (!keyword_icon_->parent()) |
| 198 AddChildView(keyword_icon_.get()); | 197 AddChildView(keyword_icon_.get()); |
| 199 } else if (keyword_icon_->parent()) { | 198 } else if (keyword_icon_->parent()) { |
| 200 RemoveChildView(keyword_icon_.get()); | 199 RemoveChildView(keyword_icon_.get()); |
| 201 } | 200 } |
| 202 | 201 |
| 203 Layout(); | 202 Layout(); |
| 204 } | 203 } |
| 205 | 204 |
| 206 void AutocompleteResultView::ShowKeyword(bool show_keyword) { | 205 void OmniboxResultView::ShowKeyword(bool show_keyword) { |
| 207 if (show_keyword) | 206 if (show_keyword) |
| 208 animation_->Show(); | 207 animation_->Show(); |
| 209 else | 208 else |
| 210 animation_->Hide(); | 209 animation_->Hide(); |
| 211 } | 210 } |
| 212 | 211 |
| 213 void AutocompleteResultView::Invalidate() { | 212 void OmniboxResultView::Invalidate() { |
| 214 keyword_icon_->SetImage(GetKeywordIcon()); | 213 keyword_icon_->SetImage(GetKeywordIcon()); |
| 215 SchedulePaint(); | 214 SchedulePaint(); |
| 216 } | 215 } |
| 217 | 216 |
| 218 gfx::Size AutocompleteResultView::GetPreferredSize() { | 217 gfx::Size OmniboxResultView::GetPreferredSize() { |
| 219 return gfx::Size(0, std::max( | 218 return gfx::Size(0, std::max( |
| 220 default_icon_size_ + (kMinimumIconVerticalPadding * 2), | 219 default_icon_size_ + (kMinimumIconVerticalPadding * 2), |
| 221 GetTextHeight() + (minimum_text_vertical_padding_ * 2))); | 220 GetTextHeight() + (minimum_text_vertical_padding_ * 2))); |
| 222 } | 221 } |
| 223 | 222 |
| 224 //////////////////////////////////////////////////////////////////////////////// | 223 //////////////////////////////////////////////////////////////////////////////// |
| 225 // AutocompleteResultView, protected: | 224 // OmniboxResultView, protected: |
| 226 | 225 |
| 227 AutocompleteResultView::ResultViewState | 226 OmniboxResultView::ResultViewState OmniboxResultView::GetState() const { |
| 228 AutocompleteResultView::GetState() const { | |
| 229 if (model_->IsSelectedIndex(model_index_)) | 227 if (model_->IsSelectedIndex(model_index_)) |
| 230 return SELECTED; | 228 return SELECTED; |
| 231 return model_->IsHoveredIndex(model_index_) ? HOVERED : NORMAL; | 229 return model_->IsHoveredIndex(model_index_) ? HOVERED : NORMAL; |
| 232 } | 230 } |
| 233 | 231 |
| 234 void AutocompleteResultView::PaintMatch(gfx::Canvas* canvas, | 232 void OmniboxResultView::PaintMatch(gfx::Canvas* canvas, |
| 235 const AutocompleteMatch& match, | 233 const AutocompleteMatch& match, |
| 236 int x) { | 234 int x) { |
| 237 x = DrawString(canvas, match.contents, match.contents_class, false, x, | 235 x = DrawString(canvas, match.contents, match.contents_class, false, x, |
| 238 text_bounds_.y()); | 236 text_bounds_.y()); |
| 239 | 237 |
| 240 // Paint the description. | 238 // Paint the description. |
| 241 // TODO(pkasting): Because we paint in multiple separate pieces, we can wind | 239 // TODO(pkasting): Because we paint in multiple separate pieces, we can wind |
| 242 // up with no space even for an ellipsis for one or both of these pieces. | 240 // up with no space even for an ellipsis for one or both of these pieces. |
| 243 // Instead, we should paint the entire match as a single long string. This | 241 // Instead, we should paint the entire match as a single long string. This |
| 244 // would also let us use a more properly-localizable string than we get with | 242 // would also let us use a more properly-localizable string than we get with |
| 245 // just the IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR. | 243 // just the IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR. |
| 246 if (!match.description.empty()) { | 244 if (!match.description.empty()) { |
| 247 string16 separator = | 245 string16 separator = |
| 248 l10n_util::GetStringUTF16(IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR); | 246 l10n_util::GetStringUTF16(IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR); |
| 249 ACMatchClassifications classifications; | 247 ACMatchClassifications classifications; |
| 250 classifications.push_back( | 248 classifications.push_back( |
| 251 ACMatchClassification(0, ACMatchClassification::NONE)); | 249 ACMatchClassification(0, ACMatchClassification::NONE)); |
| 252 x = DrawString(canvas, separator, classifications, true, x, | 250 x = DrawString(canvas, separator, classifications, true, x, |
| 253 text_bounds_.y()); | 251 text_bounds_.y()); |
| 254 | 252 |
| 255 DrawString(canvas, match.description, match.description_class, true, x, | 253 DrawString(canvas, match.description, match.description_class, true, x, |
| 256 text_bounds_.y()); | 254 text_bounds_.y()); |
| 257 } | 255 } |
| 258 } | 256 } |
| 259 | 257 |
| 260 int AutocompleteResultView::GetTextHeight() const { | 258 int OmniboxResultView::GetTextHeight() const { |
| 261 return std::max(normal_font_.GetHeight(), bold_font_.GetHeight()); | 259 return std::max(normal_font_.GetHeight(), bold_font_.GetHeight()); |
| 262 } | 260 } |
| 263 | 261 |
| 264 // static | 262 // static |
| 265 bool AutocompleteResultView::SortRunsLogically(const RunData& lhs, | 263 bool OmniboxResultView::SortRunsLogically(const RunData& lhs, |
| 266 const RunData& rhs) { | 264 const RunData& rhs) { |
| 267 return lhs.run_start < rhs.run_start; | 265 return lhs.run_start < rhs.run_start; |
| 268 } | 266 } |
| 269 | 267 |
| 270 // static | 268 // static |
| 271 bool AutocompleteResultView::SortRunsVisually(const RunData& lhs, | 269 bool OmniboxResultView::SortRunsVisually(const RunData& lhs, |
| 272 const RunData& rhs) { | 270 const RunData& rhs) { |
| 273 return lhs.visual_order < rhs.visual_order; | 271 return lhs.visual_order < rhs.visual_order; |
| 274 } | 272 } |
| 275 | 273 |
| 276 // static | 274 // static |
| 277 int AutocompleteResultView::default_icon_size_ = 0; | 275 int OmniboxResultView::default_icon_size_ = 0; |
| 278 | 276 |
| 279 const SkBitmap* AutocompleteResultView::GetIcon() const { | 277 const SkBitmap* OmniboxResultView::GetIcon() const { |
| 280 const SkBitmap* bitmap = model_->GetIconIfExtensionMatch(model_index_); | 278 const SkBitmap* bitmap = model_->GetIconIfExtensionMatch(model_index_); |
| 281 if (bitmap) | 279 if (bitmap) |
| 282 return bitmap; | 280 return bitmap; |
| 283 | 281 |
| 284 int icon = match_.starred ? | 282 int icon = match_.starred ? |
| 285 IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match_.type); | 283 IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match_.type); |
| 286 if (GetState() == SELECTED) { | 284 if (GetState() == SELECTED) { |
| 287 switch (icon) { | 285 switch (icon) { |
| 288 case IDR_OMNIBOX_EXTENSION_APP: | 286 case IDR_OMNIBOX_EXTENSION_APP: |
| 289 icon = IDR_OMNIBOX_EXTENSION_APP_SELECTED; | 287 icon = IDR_OMNIBOX_EXTENSION_APP_SELECTED; |
| 290 break; | 288 break; |
| 291 case IDR_OMNIBOX_HTTP: | 289 case IDR_OMNIBOX_HTTP: |
| 292 icon = IDR_OMNIBOX_HTTP_SELECTED; | 290 icon = IDR_OMNIBOX_HTTP_SELECTED; |
| 293 break; | 291 break; |
| 294 case IDR_OMNIBOX_SEARCH: | 292 case IDR_OMNIBOX_SEARCH: |
| 295 icon = IDR_OMNIBOX_SEARCH_SELECTED; | 293 icon = IDR_OMNIBOX_SEARCH_SELECTED; |
| 296 break; | 294 break; |
| 297 case IDR_OMNIBOX_STAR: | 295 case IDR_OMNIBOX_STAR: |
| 298 icon = IDR_OMNIBOX_STAR_SELECTED; | 296 icon = IDR_OMNIBOX_STAR_SELECTED; |
| 299 break; | 297 break; |
| 300 default: | 298 default: |
| 301 NOTREACHED(); | 299 NOTREACHED(); |
| 302 break; | 300 break; |
| 303 } | 301 } |
| 304 } | 302 } |
| 305 return ui::ResourceBundle::GetSharedInstance().GetBitmapNamed(icon); | 303 return ui::ResourceBundle::GetSharedInstance().GetBitmapNamed(icon); |
| 306 } | 304 } |
| 307 | 305 |
| 308 const gfx::ImageSkia* AutocompleteResultView::GetKeywordIcon() const { | 306 const gfx::ImageSkia* OmniboxResultView::GetKeywordIcon() const { |
| 309 // NOTE: If we ever begin returning icons of varying size, then callers need | 307 // NOTE: If we ever begin returning icons of varying size, then callers need |
| 310 // to ensure that |keyword_icon_| is resized each time its image is reset. | 308 // to ensure that |keyword_icon_| is resized each time its image is reset. |
| 311 return ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | 309 return ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
| 312 (GetState() == SELECTED) ? IDR_OMNIBOX_TTS_SELECTED : IDR_OMNIBOX_TTS); | 310 (GetState() == SELECTED) ? IDR_OMNIBOX_TTS_SELECTED : IDR_OMNIBOX_TTS); |
| 313 } | 311 } |
| 314 | 312 |
| 315 int AutocompleteResultView::DrawString( | 313 int OmniboxResultView::DrawString( |
| 316 gfx::Canvas* canvas, | 314 gfx::Canvas* canvas, |
| 317 const string16& text, | 315 const string16& text, |
| 318 const ACMatchClassifications& classifications, | 316 const ACMatchClassifications& classifications, |
| 319 bool force_dim, | 317 bool force_dim, |
| 320 int x, | 318 int x, |
| 321 int y) { | 319 int y) { |
| 322 if (text.empty()) | 320 if (text.empty()) |
| 323 return x; | 321 return x; |
| 324 | 322 |
| 325 // Check whether or not this text is a URL. URLs are always displayed LTR | 323 // Check whether or not this text is a URL. URLs are always displayed LTR |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 canvas->DrawStringInt(j->text, *j->font, j->color, left, y, | 471 canvas->DrawStringInt(j->text, *j->font, j->color, left, y, |
| 474 j->pixel_size.width(), j->pixel_size.height(), | 472 j->pixel_size.width(), j->pixel_size.height(), |
| 475 flags); | 473 flags); |
| 476 x += j->pixel_size.width(); | 474 x += j->pixel_size.width(); |
| 477 } | 475 } |
| 478 } | 476 } |
| 479 | 477 |
| 480 return x; | 478 return x; |
| 481 } | 479 } |
| 482 | 480 |
| 483 void AutocompleteResultView::Elide(Runs* runs, int remaining_width) const { | 481 void OmniboxResultView::Elide(Runs* runs, int remaining_width) const { |
| 484 // The complexity of this function is due to edge cases like the following: | 482 // The complexity of this function is due to edge cases like the following: |
| 485 // We have 100 px of available space, an initial classification that takes 86 | 483 // We have 100 px of available space, an initial classification that takes 86 |
| 486 // px, and a font that has a 15 px wide ellipsis character. Now if the first | 484 // px, and a font that has a 15 px wide ellipsis character. Now if the first |
| 487 // classification is followed by several very narrow classifications (e.g. 3 | 485 // classification is followed by several very narrow classifications (e.g. 3 |
| 488 // px wide each), we don't know whether we need to elide or not at the time we | 486 // px wide each), we don't know whether we need to elide or not at the time we |
| 489 // see the first classification -- it depends on how many subsequent | 487 // see the first classification -- it depends on how many subsequent |
| 490 // classifications follow, and some of those may be in the next run (or | 488 // classifications follow, and some of those may be in the next run (or |
| 491 // several runs!). This is why instead we let our caller move forward until | 489 // several runs!). This is why instead we let our caller move forward until |
| 492 // we know we definitely need to elide, and then in this function we move | 490 // we know we definitely need to elide, and then in this function we move |
| 493 // backward again until we find a string that we can successfully do the | 491 // backward again until we find a string that we can successfully do the |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 // ellipsis we'll append to it, or | 559 // ellipsis we'll append to it, or |
| 562 // * It is also bold, in which case we don't want to fall back | 560 // * It is also bold, in which case we don't want to fall back |
| 563 // to a normal ellipsis anyway (see comment above). | 561 // to a normal ellipsis anyway (see comment above). |
| 564 } | 562 } |
| 565 } | 563 } |
| 566 | 564 |
| 567 // We couldn't draw anything. | 565 // We couldn't draw anything. |
| 568 runs->clear(); | 566 runs->clear(); |
| 569 } | 567 } |
| 570 | 568 |
| 571 void AutocompleteResultView::Layout() { | 569 void OmniboxResultView::Layout() { |
| 572 const SkBitmap* icon = GetIcon(); | 570 const SkBitmap* icon = GetIcon(); |
| 573 | 571 |
| 574 icon_bounds_.SetRect(edge_item_padding_ + | 572 icon_bounds_.SetRect(edge_item_padding_ + |
| 575 ((icon->width() == default_icon_size_) ? | 573 ((icon->width() == default_icon_size_) ? |
| 576 0 : LocationBarView::kIconInternalPadding), | 574 0 : LocationBarView::kIconInternalPadding), |
| 577 (height() - icon->height()) / 2, icon->width(), icon->height()); | 575 (height() - icon->height()) / 2, icon->width(), icon->height()); |
| 578 | 576 |
| 579 int text_x = edge_item_padding_ + default_icon_size_ + item_padding_; | 577 int text_x = edge_item_padding_ + default_icon_size_ + item_padding_; |
| 580 int text_height = GetTextHeight(); | 578 int text_height = GetTextHeight(); |
| 581 int text_width; | 579 int text_width; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 594 keyword_icon_->SetPosition(gfx::Point(kw_x, | 592 keyword_icon_->SetPosition(gfx::Point(kw_x, |
| 595 (height() - keyword_icon_->height()) / 2)); | 593 (height() - keyword_icon_->height()) / 2)); |
| 596 } else { | 594 } else { |
| 597 text_width = width() - text_x - edge_item_padding_; | 595 text_width = width() - text_x - edge_item_padding_; |
| 598 } | 596 } |
| 599 | 597 |
| 600 text_bounds_.SetRect(text_x, std::max(0, (height() - text_height) / 2), | 598 text_bounds_.SetRect(text_x, std::max(0, (height() - text_height) / 2), |
| 601 std::max(text_width, 0), text_height); | 599 std::max(text_width, 0), text_height); |
| 602 } | 600 } |
| 603 | 601 |
| 604 void AutocompleteResultView::OnBoundsChanged( | 602 void OmniboxResultView::OnBoundsChanged(const gfx::Rect& previous_bounds) { |
| 605 const gfx::Rect& previous_bounds) { | |
| 606 animation_->SetSlideDuration(width() / 4); | 603 animation_->SetSlideDuration(width() / 4); |
| 607 } | 604 } |
| 608 | 605 |
| 609 void AutocompleteResultView::OnPaint(gfx::Canvas* canvas) { | 606 void OmniboxResultView::OnPaint(gfx::Canvas* canvas) { |
| 610 const ResultViewState state = GetState(); | 607 const ResultViewState state = GetState(); |
| 611 if (state != NORMAL) | 608 if (state != NORMAL) |
| 612 canvas->DrawColor(GetColor(state, BACKGROUND)); | 609 canvas->DrawColor(GetColor(state, BACKGROUND)); |
| 613 | 610 |
| 614 if (!match_.associated_keyword.get() || | 611 if (!match_.associated_keyword.get() || |
| 615 keyword_icon_->x() > icon_bounds_.right()) { | 612 keyword_icon_->x() > icon_bounds_.right()) { |
| 616 // Paint the icon. | 613 // Paint the icon. |
| 617 canvas->DrawImageInt(*GetIcon(), GetMirroredXForRect(icon_bounds_), | 614 canvas->DrawImageInt(*GetIcon(), GetMirroredXForRect(icon_bounds_), |
| 618 icon_bounds_.y()); | 615 icon_bounds_.y()); |
| 619 | 616 |
| 620 // Paint the text. | 617 // Paint the text. |
| 621 int x = GetMirroredXForRect(text_bounds_); | 618 int x = GetMirroredXForRect(text_bounds_); |
| 622 mirroring_context_->Initialize(x, text_bounds_.width()); | 619 mirroring_context_->Initialize(x, text_bounds_.width()); |
| 623 PaintMatch(canvas, match_, x); | 620 PaintMatch(canvas, match_, x); |
| 624 } | 621 } |
| 625 | 622 |
| 626 if (match_.associated_keyword.get()) { | 623 if (match_.associated_keyword.get()) { |
| 627 // Paint the keyword text. | 624 // Paint the keyword text. |
| 628 int x = GetMirroredXForRect(keyword_text_bounds_); | 625 int x = GetMirroredXForRect(keyword_text_bounds_); |
| 629 mirroring_context_->Initialize(x, keyword_text_bounds_.width()); | 626 mirroring_context_->Initialize(x, keyword_text_bounds_.width()); |
| 630 PaintMatch(canvas, *match_.associated_keyword.get(), x); | 627 PaintMatch(canvas, *match_.associated_keyword.get(), x); |
| 631 } | 628 } |
| 632 } | 629 } |
| 633 | 630 |
| 634 void AutocompleteResultView::AnimationProgressed( | 631 void OmniboxResultView::AnimationProgressed(const ui::Animation* animation) { |
| 635 const ui::Animation* animation) { | |
| 636 Layout(); | 632 Layout(); |
| 637 SchedulePaint(); | 633 SchedulePaint(); |
| 638 } | 634 } |
| OLD | NEW |