| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this |
| 2 // source code is governed by a BSD-style license that can be found in the | 2 // source code is governed by a BSD-style license that can be found in the |
| 3 // LICENSE file. | 3 // LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h" | 5 #include "chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h" |
| 6 | 6 |
| 7 #include <dwmapi.h> | 7 #include <dwmapi.h> |
| 8 | 8 |
| 9 #include "chrome/browser/autocomplete/autocomplete_edit_view_win.h" | 9 #include "chrome/browser/autocomplete/autocomplete_edit_view_win.h" |
| 10 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" | 10 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" |
| 11 #include "chrome/browser/views/autocomplete/autocomplete_popup_win.h" | 11 #include "chrome/browser/views/autocomplete/autocomplete_popup_win.h" |
| 12 #include "chrome/common/gfx/chrome_canvas.h" | 12 #include "chrome/common/gfx/chrome_canvas.h" |
| 13 #include "chrome/common/gfx/color_utils.h" | 13 #include "chrome/common/gfx/color_utils.h" |
| 14 #include "chrome/common/gfx/insets.h" | 14 #include "chrome/common/gfx/insets.h" |
| 15 #include "chrome/common/gfx/path.h" | 15 #include "chrome/common/gfx/path.h" |
| 16 #include "chrome/common/l10n_util.h" | 16 #include "chrome/common/l10n_util.h" |
| 17 #include "chrome/common/resource_bundle.h" | 17 #include "chrome/common/resource_bundle.h" |
| 18 #include "chrome/views/widget/widget.h" | 18 #include "chrome/views/widget/widget.h" |
| 19 #include "grit/generated_resources.h" |
| 19 #include "grit/theme_resources.h" | 20 #include "grit/theme_resources.h" |
| 20 #include "skia/include/SkShader.h" | 21 #include "skia/include/SkShader.h" |
| 21 #include "third_party/icu38/public/common/unicode/ubidi.h" | 22 #include "third_party/icu38/public/common/unicode/ubidi.h" |
| 22 | 23 |
| 23 static const SkColor kTransparentColor = SkColorSetARGB(0, 0, 0, 0); | 24 // Colors for various components of the view. |
| 25 static const SkColor kBackgroundColor = |
| 26 color_utils::GetSysSkColor(COLOR_WINDOW); |
| 27 static const SkColor kSelectedBackgroundColor = |
| 28 color_utils::GetSysSkColor(COLOR_HIGHLIGHT); |
| 29 static const SkColor kHoverBackgroundColor = |
| 30 SkColorSetA(kSelectedBackgroundColor, 127); |
| 31 static const SkColor kTextColor = |
| 32 color_utils::GetSysSkColor(COLOR_WINDOWTEXT); |
| 33 static const SkColor kSelectedTextColor = |
| 34 color_utils::GetSysSkColor(COLOR_HIGHLIGHTTEXT); |
| 35 static const SkColor kDimTextColor = |
| 36 color_utils::GetSysSkColor(COLOR_GRAYTEXT); |
| 37 static const SkColor kSelectedDimTextColor = |
| 38 color_utils::GetSysSkColor(COLOR_HIGHLIGHTTEXT); |
| 24 static const SkColor kStandardURLColor = SkColorSetRGB(0, 0x80, 0); | 39 static const SkColor kStandardURLColor = SkColorSetRGB(0, 0x80, 0); |
| 25 static const SkColor kHighlightURLColor = SkColorSetRGB(0xD0, 0xFF, 0xD0); | 40 static const SkColor kHighlightURLColor = SkColorSetRGB(0xD0, 0xFF, 0xD0); |
| 26 static const int kPopupTransparency = 235; | 41 static const int kPopupTransparency = 235; |
| 27 static const int kHoverRowAlpha = 0x40; | 42 static const int kHoverRowAlpha = 0x40; |
| 28 // The minimum distance between the top and bottom of the icon and the top or | 43 // The minimum distance between the top and bottom of the icon and the top or |
| 29 // bottom of the row. "Minimum" is used because the vertical padding may be | 44 // bottom of the row. "Minimum" is used because the vertical padding may be |
| 30 // larger, depending on the size of the text. | 45 // larger, depending on the size of the text. |
| 31 static const int kIconVerticalPadding = 2; | 46 static const int kIconVerticalPadding = 2; |
| 32 // The minimum distance between the top and bottom of the text and the top or | 47 // The minimum distance between the top and bottom of the text and the top or |
| 33 // bottom of the row. See comment about the use of "minimum" for | 48 // bottom of the row. See comment about the use of "minimum" for |
| (...skipping 26 matching lines...) Expand all Loading... |
| 60 virtual bool OnMouseDragged(const views::MouseEvent& event); | 75 virtual bool OnMouseDragged(const views::MouseEvent& event); |
| 61 | 76 |
| 62 private: | 77 private: |
| 63 // Get colors for row backgrounds and text for different row states. | 78 // Get colors for row backgrounds and text for different row states. |
| 64 SkColor GetBackgroundColor() const; | 79 SkColor GetBackgroundColor() const; |
| 65 SkColor GetTextColor() const; | 80 SkColor GetTextColor() const; |
| 66 | 81 |
| 67 SkBitmap* GetIcon() const; | 82 SkBitmap* GetIcon() const; |
| 68 | 83 |
| 69 // Draws the specified |text| into the canvas, using highlighting provided by | 84 // Draws the specified |text| into the canvas, using highlighting provided by |
| 70 // |classifications|. | 85 // |classifications|. If |force_dim| is true, ACMatchClassification::DIM is |
| 71 void DrawString(ChromeCanvas* canvas, | 86 // added to all of the classifications. Returns the x position to the right |
| 87 // of the string. |
| 88 int DrawString(ChromeCanvas* canvas, |
| 72 const std::wstring& text, | 89 const std::wstring& text, |
| 73 const ACMatchClassifications& classifications, | 90 const ACMatchClassifications& classifications, |
| 91 bool force_dim, |
| 74 int x, | 92 int x, |
| 75 int y); | 93 int y); |
| 76 | 94 |
| 77 // Draws an individual sub-fragment with the specified style. | 95 // Draws an individual sub-fragment with the specified style. Returns the x |
| 96 // position to the right of the fragment. |
| 78 int DrawStringFragment(ChromeCanvas* canvas, | 97 int DrawStringFragment(ChromeCanvas* canvas, |
| 79 const std::wstring& text, | 98 const std::wstring& text, |
| 80 int style, | 99 int style, |
| 81 int x, | 100 int x, |
| 82 int y); | 101 int y); |
| 83 | 102 |
| 84 // Gets the font and text color for a fragment with the specified style. | 103 // Gets the font and text color for a fragment with the specified style. |
| 85 ChromeFont GetFragmentFont(int style) const; | 104 ChromeFont GetFragmentFont(int style) const; |
| 86 SkColor GetFragmentTextColor(int style) const; | 105 SkColor GetFragmentTextColor(int style) const; |
| 87 | 106 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 98 // A context used for mirroring regions. | 117 // A context used for mirroring regions. |
| 99 class MirroringContext; | 118 class MirroringContext; |
| 100 scoped_ptr<MirroringContext> mirroring_context_; | 119 scoped_ptr<MirroringContext> mirroring_context_; |
| 101 | 120 |
| 102 // Layout rects for various sub-components of the view. | 121 // Layout rects for various sub-components of the view. |
| 103 gfx::Rect icon_bounds_; | 122 gfx::Rect icon_bounds_; |
| 104 gfx::Rect text_bounds_; | 123 gfx::Rect text_bounds_; |
| 105 | 124 |
| 106 // Icons for rows. | 125 // Icons for rows. |
| 107 static SkBitmap* icon_url_; | 126 static SkBitmap* icon_url_; |
| 127 static SkBitmap* icon_url_selected_; |
| 108 static SkBitmap* icon_history_; | 128 static SkBitmap* icon_history_; |
| 129 static SkBitmap* icon_history_selected_; |
| 109 static SkBitmap* icon_search_; | 130 static SkBitmap* icon_search_; |
| 131 static SkBitmap* icon_search_selected_; |
| 110 static SkBitmap* icon_more_; | 132 static SkBitmap* icon_more_; |
| 133 static SkBitmap* icon_more_selected_; |
| 111 static SkBitmap* icon_star_; | 134 static SkBitmap* icon_star_; |
| 135 static SkBitmap* icon_star_selected_; |
| 112 static int icon_size_; | 136 static int icon_size_; |
| 113 | 137 |
| 114 static bool initialized_; | 138 static bool initialized_; |
| 115 static void InitClass(); | 139 static void InitClass(); |
| 116 | 140 |
| 117 DISALLOW_COPY_AND_ASSIGN(AutocompleteResultView); | 141 DISALLOW_COPY_AND_ASSIGN(AutocompleteResultView); |
| 118 }; | 142 }; |
| 119 | 143 |
| 120 // static | 144 // static |
| 121 SkBitmap* AutocompleteResultView::icon_url_ = NULL; | 145 SkBitmap* AutocompleteResultView::icon_url_ = NULL; |
| 146 SkBitmap* AutocompleteResultView::icon_url_selected_ = NULL; |
| 122 SkBitmap* AutocompleteResultView::icon_history_ = NULL; | 147 SkBitmap* AutocompleteResultView::icon_history_ = NULL; |
| 148 SkBitmap* AutocompleteResultView::icon_history_selected_ = NULL; |
| 123 SkBitmap* AutocompleteResultView::icon_search_ = NULL; | 149 SkBitmap* AutocompleteResultView::icon_search_ = NULL; |
| 150 SkBitmap* AutocompleteResultView::icon_search_selected_ = NULL; |
| 124 SkBitmap* AutocompleteResultView::icon_star_ = NULL; | 151 SkBitmap* AutocompleteResultView::icon_star_ = NULL; |
| 152 SkBitmap* AutocompleteResultView::icon_star_selected_ = NULL; |
| 125 SkBitmap* AutocompleteResultView::icon_more_ = NULL; | 153 SkBitmap* AutocompleteResultView::icon_more_ = NULL; |
| 154 SkBitmap* AutocompleteResultView::icon_more_selected_ = NULL; |
| 126 int AutocompleteResultView::icon_size_ = 0; | 155 int AutocompleteResultView::icon_size_ = 0; |
| 127 bool AutocompleteResultView::initialized_ = false; | 156 bool AutocompleteResultView::initialized_ = false; |
| 128 | 157 |
| 129 // This class implements a utility used for mirroring x-coordinates when the | 158 // This class implements a utility used for mirroring x-coordinates when the |
| 130 // application language is a right-to-left one. | 159 // application language is a right-to-left one. |
| 131 class AutocompleteResultView::MirroringContext { | 160 class AutocompleteResultView::MirroringContext { |
| 132 public: | 161 public: |
| 133 MirroringContext() : min_x_(0), center_x_(0), max_x_(0), enabled_(false) { } | 162 MirroringContext() : min_x_(0), center_x_(0), max_x_(0), enabled_(false) { } |
| 134 | 163 |
| 135 // Initializes the bounding region used for mirroring coordinates. | 164 // Initializes the bounding region used for mirroring coordinates. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 mirroring_context_(new MirroringContext()) { | 212 mirroring_context_(new MirroringContext()) { |
| 184 InitClass(); | 213 InitClass(); |
| 185 } | 214 } |
| 186 | 215 |
| 187 AutocompleteResultView::~AutocompleteResultView() { | 216 AutocompleteResultView::~AutocompleteResultView() { |
| 188 } | 217 } |
| 189 | 218 |
| 190 void AutocompleteResultView::Paint(ChromeCanvas* canvas) { | 219 void AutocompleteResultView::Paint(ChromeCanvas* canvas) { |
| 191 canvas->FillRectInt(GetBackgroundColor(), 0, 0, width(), height()); | 220 canvas->FillRectInt(GetBackgroundColor(), 0, 0, width(), height()); |
| 192 | 221 |
| 222 int x = MirroredLeftPointForRect(icon_bounds_); |
| 223 |
| 193 // Paint the icon. | 224 // Paint the icon. |
| 194 canvas->DrawBitmapInt(*GetIcon(), icon_bounds_.x(), icon_bounds_.y()); | 225 canvas->DrawBitmapInt(*GetIcon(), x, icon_bounds_.y()); |
| 226 |
| 227 const AutocompleteMatch& match = model_->GetMatchAtIndex(model_index_); |
| 195 | 228 |
| 196 // Paint the text. | 229 // Paint the text. |
| 197 const AutocompleteMatch& match = model_->GetMatchAtIndex(model_index_); | 230 x = MirroredLeftPointForRect(text_bounds_); |
| 198 DrawString(canvas, match.contents, match.contents_class, | 231 x = DrawString(canvas, match.contents, match.contents_class, false, x, |
| 199 text_bounds_.x(), text_bounds_.y()); | 232 text_bounds_.y()); |
| 200 | 233 |
| 201 // Paint the description. | 234 // Paint the description. |
| 202 // TODO(beng): do this. | 235 if (!match.description.empty()) { |
| 236 std::wstring separator = |
| 237 l10n_util::GetString(IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR); |
| 238 ACMatchClassifications classifications; |
| 239 classifications.push_back( |
| 240 ACMatchClassification(0, ACMatchClassification::NONE)); |
| 241 x = DrawString(canvas, separator, classifications, true, x, |
| 242 text_bounds_.y()); |
| 243 |
| 244 x = DrawString(canvas, match.description, match.description_class, true, x, |
| 245 text_bounds_.y()); |
| 246 } |
| 203 } | 247 } |
| 204 | 248 |
| 205 void AutocompleteResultView::Layout() { | 249 void AutocompleteResultView::Layout() { |
| 206 icon_bounds_.SetRect(kRowLeftPadding, (height() - icon_size_) / 2, | 250 icon_bounds_.SetRect(kRowLeftPadding, (height() - icon_size_) / 2, |
| 207 icon_size_, icon_size_); | 251 icon_size_, icon_size_); |
| 208 int text_x = icon_bounds_.right() + kIconTextSpacing; | 252 int text_x = icon_bounds_.right() + kIconTextSpacing; |
| 209 text_bounds_.SetRect(text_x, (height() - font_.height()) / 2, | 253 text_bounds_.SetRect(text_x, (height() - font_.height()) / 2, |
| 210 bounds().right() - text_x - kRowRightPadding, | 254 bounds().right() - text_x - kRowRightPadding, |
| 211 font_.height()); | 255 font_.height()); |
| 212 } | 256 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 } | 299 } |
| 256 | 300 |
| 257 bool AutocompleteResultView::OnMouseDragged(const views::MouseEvent& event) { | 301 bool AutocompleteResultView::OnMouseDragged(const views::MouseEvent& event) { |
| 258 // TODO(beng): move all message handling into the contents view and override | 302 // TODO(beng): move all message handling into the contents view and override |
| 259 // GetViewForPoint. | 303 // GetViewForPoint. |
| 260 return false; | 304 return false; |
| 261 } | 305 } |
| 262 | 306 |
| 263 SkColor AutocompleteResultView::GetBackgroundColor() const { | 307 SkColor AutocompleteResultView::GetBackgroundColor() const { |
| 264 if (model_->IsSelectedIndex(model_index_)) | 308 if (model_->IsSelectedIndex(model_index_)) |
| 265 return color_utils::GetSysSkColor(COLOR_HIGHLIGHT); | 309 return kSelectedBackgroundColor; |
| 266 if (hot_) { | 310 return hot_ ? kHoverBackgroundColor : kBackgroundColor; |
| 267 COLORREF color = GetSysColor(COLOR_HIGHLIGHT); | |
| 268 return SkColorSetARGB(kHoverRowAlpha, GetRValue(color), GetGValue(color), | |
| 269 GetBValue(color)); | |
| 270 } | |
| 271 return kTransparentColor; | |
| 272 } | 311 } |
| 273 | 312 |
| 274 SkColor AutocompleteResultView::GetTextColor() const { | 313 SkColor AutocompleteResultView::GetTextColor() const { |
| 275 if (model_->IsSelectedIndex(model_index_)) | 314 return model_->IsSelectedIndex(model_index_) ? kSelectedTextColor |
| 276 return color_utils::GetSysSkColor(COLOR_HIGHLIGHTTEXT); | 315 : kTextColor; |
| 277 return color_utils::GetSysSkColor(COLOR_WINDOWTEXT); | |
| 278 } | 316 } |
| 279 | 317 |
| 280 SkBitmap* AutocompleteResultView::GetIcon() const { | 318 SkBitmap* AutocompleteResultView::GetIcon() const { |
| 319 bool selected = model_->IsSelectedIndex(model_index_); |
| 281 switch (model_->GetMatchAtIndex(model_index_).type) { | 320 switch (model_->GetMatchAtIndex(model_index_).type) { |
| 282 case AutocompleteMatch::URL_WHAT_YOU_TYPED: | 321 case AutocompleteMatch::URL_WHAT_YOU_TYPED: |
| 283 case AutocompleteMatch::HISTORY_URL: | 322 case AutocompleteMatch::HISTORY_URL: |
| 284 case AutocompleteMatch::NAVSUGGEST: | 323 case AutocompleteMatch::NAVSUGGEST: |
| 285 return icon_url_; | 324 return selected ? icon_url_selected_ : icon_url_; |
| 286 case AutocompleteMatch::HISTORY_TITLE: | 325 case AutocompleteMatch::HISTORY_TITLE: |
| 287 case AutocompleteMatch::HISTORY_BODY: | 326 case AutocompleteMatch::HISTORY_BODY: |
| 288 case AutocompleteMatch::HISTORY_KEYWORD: | 327 case AutocompleteMatch::HISTORY_KEYWORD: |
| 289 return icon_history_; | 328 return selected ? icon_history_selected_ : icon_history_; |
| 290 case AutocompleteMatch::SEARCH_WHAT_YOU_TYPED: | 329 case AutocompleteMatch::SEARCH_WHAT_YOU_TYPED: |
| 291 case AutocompleteMatch::SEARCH_HISTORY: | 330 case AutocompleteMatch::SEARCH_HISTORY: |
| 292 case AutocompleteMatch::SEARCH_SUGGEST: | 331 case AutocompleteMatch::SEARCH_SUGGEST: |
| 293 case AutocompleteMatch::SEARCH_OTHER_ENGINE: | 332 case AutocompleteMatch::SEARCH_OTHER_ENGINE: |
| 294 return icon_search_; | 333 return selected ? icon_search_selected_ : icon_search_; |
| 295 case AutocompleteMatch::OPEN_HISTORY_PAGE: | 334 case AutocompleteMatch::OPEN_HISTORY_PAGE: |
| 296 return icon_more_; | 335 return selected ? icon_more_selected_ : icon_more_; |
| 297 default: | 336 default: |
| 298 NOTREACHED(); | 337 NOTREACHED(); |
| 299 break; | 338 break; |
| 300 } | 339 } |
| 301 return NULL; | 340 return NULL; |
| 302 } | 341 } |
| 303 | 342 |
| 304 void AutocompleteResultView::DrawString( | 343 int AutocompleteResultView::DrawString( |
| 305 ChromeCanvas* canvas, | 344 ChromeCanvas* canvas, |
| 306 const std::wstring& text, | 345 const std::wstring& text, |
| 307 const ACMatchClassifications& classifications, | 346 const ACMatchClassifications& classifications, |
| 347 bool force_dim, |
| 308 int x, | 348 int x, |
| 309 int y) { | 349 int y) { |
| 310 if (!text.length()) | 350 if (!text.length()) |
| 311 return; | 351 return x; |
| 312 | 352 |
| 313 // Check whether or not this text is a URL string. | 353 // Check whether or not this text is a URL string. |
| 314 // A URL string is basically in English with possible included words in | 354 // A URL string is basically in English with possible included words in |
| 315 // Arabic or Hebrew. For such case, ICU provides a special algorithm and we | 355 // Arabic or Hebrew. For such case, ICU provides a special algorithm and we |
| 316 // should use it. | 356 // should use it. |
| 317 bool url = false; | 357 bool url = false; |
| 318 for (ACMatchClassifications::const_iterator i = classifications.begin(); | 358 for (ACMatchClassifications::const_iterator i = classifications.begin(); |
| 319 i != classifications.end(); ++i) { | 359 i != classifications.end(); ++i) { |
| 320 if (i->style & ACMatchClassification::URL) | 360 if (i->style & ACMatchClassification::URL) |
| 321 url = true; | 361 url = true; |
| 322 } | 362 } |
| 323 | 363 |
| 324 // Initialize a bidirectional line iterator of ICU and split the text into | 364 // Initialize a bidirectional line iterator of ICU and split the text into |
| 325 // visual runs. (A visual run is consecutive characters which have the same | 365 // visual runs. (A visual run is consecutive characters which have the same |
| 326 // display direction and should be displayed at once.) | 366 // display direction and should be displayed at once.) |
| 327 l10n_util::BiDiLineIterator bidi_line; | 367 l10n_util::BiDiLineIterator bidi_line; |
| 328 if (!bidi_line.Open(text, mirroring_context_->enabled(), url)) | 368 if (!bidi_line.Open(text, mirroring_context_->enabled(), url)) |
| 329 return; | 369 return x; |
| 330 const int runs = bidi_line.CountRuns(); | 370 const int runs = bidi_line.CountRuns(); |
| 331 | 371 |
| 332 // Draw the visual runs. | 372 // Draw the visual runs. |
| 333 // This loop splits each run into text fragments with the given | 373 // This loop splits each run into text fragments with the given |
| 334 // classifications and draws the text fragments. | 374 // classifications and draws the text fragments. |
| 335 // When the direction of a run is right-to-left, we have to mirror the | 375 // When the direction of a run is right-to-left, we have to mirror the |
| 336 // x-coordinate of this run and render the fragments in the right-to-left | 376 // x-coordinate of this run and render the fragments in the right-to-left |
| 337 // reading order. To handle this display order independently from the one of | 377 // reading order. To handle this display order independently from the one of |
| 338 // this popup window, this loop renders a run with the steps below: | 378 // this popup window, this loop renders a run with the steps below: |
| 339 // 1. Create a local display context for each run; | 379 // 1. Create a local display context for each run; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 363 &run_length); | 403 &run_length); |
| 364 const int run_end = run_start + run_length; | 404 const int run_end = run_start + run_length; |
| 365 | 405 |
| 366 // Split this run with the given classifications and draw the fragments | 406 // Split this run with the given classifications and draw the fragments |
| 367 // into the local display context. | 407 // into the local display context. |
| 368 for (ACMatchClassifications::const_iterator i = classifications.begin(); | 408 for (ACMatchClassifications::const_iterator i = classifications.begin(); |
| 369 i != classifications.end(); ++i) { | 409 i != classifications.end(); ++i) { |
| 370 const int text_start = std::max(run_start, static_cast<int>(i->offset)); | 410 const int text_start = std::max(run_start, static_cast<int>(i->offset)); |
| 371 const int text_end = std::min(run_end, (i != classifications.end() - 1) ? | 411 const int text_end = std::min(run_end, (i != classifications.end() - 1) ? |
| 372 static_cast<int>((i + 1)->offset) : run_end); | 412 static_cast<int>((i + 1)->offset) : run_end); |
| 413 int style = i->style; |
| 414 if (force_dim) |
| 415 style |= ACMatchClassification::DIM; |
| 373 x += DrawStringFragment(canvas, | 416 x += DrawStringFragment(canvas, |
| 374 text.substr(text_start, text_end - text_start), | 417 text.substr(text_start, text_end - text_start), |
| 375 i->style, x, y); | 418 style, x, y); |
| 376 } | 419 } |
| 377 } | 420 } |
| 421 return x; |
| 378 } | 422 } |
| 379 | 423 |
| 380 int AutocompleteResultView::DrawStringFragment( | 424 int AutocompleteResultView::DrawStringFragment( |
| 381 ChromeCanvas* canvas, | 425 ChromeCanvas* canvas, |
| 382 const std::wstring& text, | 426 const std::wstring& text, |
| 383 int style, | 427 int style, |
| 384 int x, | 428 int x, |
| 385 int y) { | 429 int y) { |
| 386 ChromeFont display_font = GetFragmentFont(style); | 430 ChromeFont display_font = GetFragmentFont(style); |
| 387 int string_width = display_font.GetStringWidth(text); | 431 int string_width = display_font.GetStringWidth(text); |
| 388 canvas->DrawStringInt(text, GetFragmentFont(style), | 432 canvas->DrawStringInt(text, GetFragmentFont(style), |
| 389 GetFragmentTextColor(style), x, y, string_width, | 433 GetFragmentTextColor(style), x, y, string_width, |
| 390 display_font.height()); | 434 display_font.height()); |
| 391 return string_width; | 435 return string_width; |
| 392 } | 436 } |
| 393 | 437 |
| 394 ChromeFont AutocompleteResultView::GetFragmentFont(int style) const { | 438 ChromeFont AutocompleteResultView::GetFragmentFont(int style) const { |
| 395 if (style & ACMatchClassification::MATCH) | 439 if (style & ACMatchClassification::MATCH) |
| 396 return font_.DeriveFont(0, ChromeFont::BOLD); | 440 return font_.DeriveFont(0, ChromeFont::BOLD); |
| 397 return font_; | 441 return font_; |
| 398 } | 442 } |
| 399 | 443 |
| 400 SkColor AutocompleteResultView::GetFragmentTextColor(int style) const { | 444 SkColor AutocompleteResultView::GetFragmentTextColor(int style) const { |
| 445 bool selected = model_->IsSelectedIndex(model_index_); |
| 401 if (style & ACMatchClassification::URL) { | 446 if (style & ACMatchClassification::URL) { |
| 402 // TODO(beng): bring over the contrast logic from the old popup and massage | 447 // TODO(beng): bring over the contrast logic from the old popup and massage |
| 403 // these values. See autocomplete_popup_view_win.cc and | 448 // these values. See autocomplete_popup_view_win.cc and |
| 404 // LuminosityContrast etc. | 449 // LuminosityContrast etc. |
| 405 return model_->IsSelectedIndex(model_index_) ? kHighlightURLColor | 450 return selected ? kHighlightURLColor : kStandardURLColor; |
| 406 : kStandardURLColor; | |
| 407 } | 451 } |
| 408 | |
| 409 if (style & ACMatchClassification::DIM) | 452 if (style & ACMatchClassification::DIM) |
| 410 return SkColorSetA(GetTextColor(), 0xAA); | 453 return selected ? kSelectedDimTextColor : kDimTextColor; |
| 411 return GetTextColor(); | 454 return GetTextColor(); |
| 412 } | 455 } |
| 413 | 456 |
| 414 void AutocompleteResultView::InitClass() { | 457 void AutocompleteResultView::InitClass() { |
| 415 if (!initialized_) { | 458 if (!initialized_) { |
| 416 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 459 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 417 icon_url_ = rb.GetBitmapNamed(IDR_O2_GLOBE); | 460 icon_url_ = rb.GetBitmapNamed(IDR_O2_GLOBE); |
| 461 icon_url_selected_ = rb.GetBitmapNamed(IDR_O2_GLOBE_SELECTED); |
| 418 icon_history_ = rb.GetBitmapNamed(IDR_O2_HISTORY); | 462 icon_history_ = rb.GetBitmapNamed(IDR_O2_HISTORY); |
| 463 icon_history_selected_ = rb.GetBitmapNamed(IDR_O2_HISTORY_SELECTED); |
| 419 icon_search_ = rb.GetBitmapNamed(IDR_O2_SEARCH); | 464 icon_search_ = rb.GetBitmapNamed(IDR_O2_SEARCH); |
| 465 icon_search_selected_ = rb.GetBitmapNamed(IDR_O2_SEARCH_SELECTED); |
| 420 icon_star_ = rb.GetBitmapNamed(IDR_O2_STAR); | 466 icon_star_ = rb.GetBitmapNamed(IDR_O2_STAR); |
| 467 icon_star_selected_ = rb.GetBitmapNamed(IDR_O2_STAR_SELECTED); |
| 421 icon_more_ = rb.GetBitmapNamed(IDR_O2_MORE); | 468 icon_more_ = rb.GetBitmapNamed(IDR_O2_MORE); |
| 469 icon_more_selected_ = rb.GetBitmapNamed(IDR_O2_MORE_SELECTED); |
| 422 // All icons are assumed to be square, and the same size. | 470 // All icons are assumed to be square, and the same size. |
| 423 icon_size_ = icon_url_->width(); | 471 icon_size_ = icon_url_->width(); |
| 424 initialized_ = true; | 472 initialized_ = true; |
| 425 } | 473 } |
| 426 } | 474 } |
| 427 | 475 |
| 428 class PopupBorder : public views::Border { | 476 class PopupBorder : public views::Border { |
| 429 public: | 477 public: |
| 430 PopupBorder() { | 478 PopupBorder() { |
| 431 InitClass(); | 479 InitClass(); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 popup_positioner_(popup_positioner), | 586 popup_positioner_(popup_positioner), |
| 539 edit_font_(font) { | 587 edit_font_(font) { |
| 540 set_border(new PopupBorder); | 588 set_border(new PopupBorder); |
| 541 } | 589 } |
| 542 | 590 |
| 543 void AutocompletePopupContentsView::UpdateResultViewsFromResult( | 591 void AutocompletePopupContentsView::UpdateResultViewsFromResult( |
| 544 const AutocompleteResult& result) { | 592 const AutocompleteResult& result) { |
| 545 RemoveAllChildViews(true); | 593 RemoveAllChildViews(true); |
| 546 for (size_t i = 0; i < result.size(); ++i) | 594 for (size_t i = 0; i < result.size(); ++i) |
| 547 AddChildView(new AutocompleteResultView(this, i, edit_font_)); | 595 AddChildView(new AutocompleteResultView(this, i, edit_font_)); |
| 596 |
| 597 // Need to schedule a paint here because if we don't and our result count |
| 598 // hasn't changed since last time we were shown, we may not repaint to |
| 599 // show selection changes. |
| 600 SchedulePaint(); |
| 548 } | 601 } |
| 549 | 602 |
| 550 gfx::Rect AutocompletePopupContentsView::GetPopupBounds() const { | 603 gfx::Rect AutocompletePopupContentsView::GetPopupBounds() const { |
| 551 gfx::Insets insets; | 604 gfx::Insets insets; |
| 552 border()->GetInsets(&insets); | 605 border()->GetInsets(&insets); |
| 553 gfx::Rect contents_bounds = popup_positioner_->GetPopupBounds(); | 606 gfx::Rect contents_bounds = popup_positioner_->GetPopupBounds(); |
| 554 int child_count = GetChildViewCount(); | 607 int child_count = GetChildViewCount(); |
| 555 int height = 0; | 608 int height = 0; |
| 556 for (int i = 0; i < child_count; ++i) | 609 for (int i = 0; i < child_count; ++i) |
| 557 height += GetChildViewAt(i)->GetPreferredSize().height(); | 610 height += GetChildViewAt(i)->GetPreferredSize().height(); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 // We paint our children in an unconventional way. | 695 // We paint our children in an unconventional way. |
| 643 // | 696 // |
| 644 // Because the border of this view creates an anti-aliased round-rect region | 697 // Because the border of this view creates an anti-aliased round-rect region |
| 645 // for the contents, we need to render our rectangular result child views into | 698 // for the contents, we need to render our rectangular result child views into |
| 646 // this round rect region. We can't use a simple clip because clipping is | 699 // this round rect region. We can't use a simple clip because clipping is |
| 647 // 1-bit and we get nasty jagged edges. | 700 // 1-bit and we get nasty jagged edges. |
| 648 // | 701 // |
| 649 // Instead, we paint all our children into a second canvas and use that as a | 702 // Instead, we paint all our children into a second canvas and use that as a |
| 650 // shader to fill a path representing the round-rect clipping region. This | 703 // shader to fill a path representing the round-rect clipping region. This |
| 651 // yields a nice anti-aliased edge. | 704 // yields a nice anti-aliased edge. |
| 652 gfx::Rect contents_rect = GetLocalBounds(false); | 705 ChromeCanvas contents_canvas(width(), height(), true); |
| 653 ChromeCanvas contents_canvas(contents_rect.width(), contents_rect.height(), | 706 contents_canvas.FillRectInt(kBackgroundColor, 0, 0, width(), height()); |
| 654 true); | |
| 655 contents_canvas.FillRectInt(color_utils::GetSysSkColor(COLOR_WINDOW), 0, 0, | |
| 656 contents_rect.width(), contents_rect.height()); | |
| 657 View::PaintChildren(&contents_canvas); | 707 View::PaintChildren(&contents_canvas); |
| 658 // We want the contents background to be slightly transparent so we can see | 708 // We want the contents background to be slightly transparent so we can see |
| 659 // the blurry glass effect on DWM systems behind. We do this _after_ we paint | 709 // the blurry glass effect on DWM systems behind. We do this _after_ we paint |
| 660 // the children since they paint text, and GDI will reset this alpha data if | 710 // the children since they paint text, and GDI will reset this alpha data if |
| 661 // we paint text after this call. | 711 // we paint text after this call. |
| 662 MakeCanvasTransparent(&contents_canvas); | 712 MakeCanvasTransparent(&contents_canvas); |
| 663 | 713 |
| 664 // Now paint the contents of the contents canvas into the actual canvas. | 714 // Now paint the contents of the contents canvas into the actual canvas. |
| 665 SkPaint paint; | 715 SkPaint paint; |
| 666 paint.setAntiAlias(true); | 716 paint.setAntiAlias(true); |
| 667 | 717 |
| 668 SkShader* shader = SkShader::CreateBitmapShader( | 718 SkShader* shader = SkShader::CreateBitmapShader( |
| 669 contents_canvas.getDevice()->accessBitmap(false), | 719 contents_canvas.getDevice()->accessBitmap(false), |
| 670 SkShader::kClamp_TileMode, | 720 SkShader::kRepeat_TileMode, |
| 671 SkShader::kClamp_TileMode); | 721 SkShader::kRepeat_TileMode); |
| 672 paint.setShader(shader); | 722 paint.setShader(shader); |
| 673 shader->unref(); | 723 shader->unref(); |
| 674 | 724 |
| 675 gfx::Path path; | 725 gfx::Path path; |
| 676 MakeContentsPath(&path, contents_rect); | 726 MakeContentsPath(&path, GetLocalBounds(false)); |
| 677 canvas->drawPath(path, paint); | 727 canvas->drawPath(path, paint); |
| 678 } | 728 } |
| 679 | 729 |
| 680 void AutocompletePopupContentsView::Layout() { | 730 void AutocompletePopupContentsView::Layout() { |
| 681 UpdateBlurRegion(); | 731 UpdateBlurRegion(); |
| 682 | 732 |
| 683 // Size our children to the available content area. | 733 // Size our children to the available content area. |
| 684 gfx::Rect contents_rect = GetLocalBounds(false); | 734 gfx::Rect contents_rect = GetLocalBounds(false); |
| 685 int child_count = GetChildViewCount(); | 735 int child_count = GetChildViewCount(); |
| 686 int top = contents_rect.y(); | 736 int top = contents_rect.y(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 ChromeCanvas* canvas) { | 788 ChromeCanvas* canvas) { |
| 739 // Allow the window blur effect to show through the popup background. | 789 // Allow the window blur effect to show through the popup background. |
| 740 SkPaint paint; | 790 SkPaint paint; |
| 741 paint.setColor(SkColorSetARGB(kPopupTransparency, 255, 255, 255)); | 791 paint.setColor(SkColorSetARGB(kPopupTransparency, 255, 255, 255)); |
| 742 paint.setPorterDuffXfermode(SkPorterDuff::kDstIn_Mode); | 792 paint.setPorterDuffXfermode(SkPorterDuff::kDstIn_Mode); |
| 743 paint.setStyle(SkPaint::kFill_Style); | 793 paint.setStyle(SkPaint::kFill_Style); |
| 744 canvas->FillRectInt(0, 0, canvas->getDevice()->width(), | 794 canvas->FillRectInt(0, 0, canvas->getDevice()->width(), |
| 745 canvas->getDevice()->height(), paint); | 795 canvas->getDevice()->height(), paint); |
| 746 } | 796 } |
| 747 | 797 |
| OLD | NEW |