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 |