Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // 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 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 #include "ui/gfx/color_utils.h" | 26 #include "ui/gfx/color_utils.h" |
| 27 #include "ui/gfx/native_theme.h" | 27 #include "ui/gfx/native_theme.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; // Default value, may be overridden. |
|
Peter Kasting
2012/05/07 21:03:12
Nit: Comment unnecessary given your comments on th
Jói
2012/05/10 18:33:07
Done.
| |
| 37 | 37 |
| 38 } // namespace | 38 } // namespace |
| 39 | 39 |
| 40 //////////////////////////////////////////////////////////////////////////////// | 40 //////////////////////////////////////////////////////////////////////////////// |
| 41 // AutocompleteResultView, public: | 41 // AutocompleteResultView, 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 AutocompleteResultView::ClassificationData { |
| 46 string16 text; | 46 string16 text; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 AutocompleteResultView::AutocompleteResultView( |
| 102 AutocompleteResultViewModel* model, | 102 AutocompleteResultViewModel* 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 : model_(model), | 106 : edge_item_padding_(LocationBarView::kEdgeItemPadding), |
| 107 item_padding_(LocationBarView::kItemPadding), | |
| 108 minimum_text_vertical_padding_(kMinimumTextVerticalPadding), | |
| 109 model_(model), | |
| 107 model_index_(model_index), | 110 model_index_(model_index), |
| 108 normal_font_(font), | 111 normal_font_(font), |
| 109 bold_font_(bold_font), | 112 bold_font_(bold_font), |
| 110 ellipsis_width_(font.GetStringWidth(string16(kEllipsis))), | 113 ellipsis_width_(font.GetStringWidth(string16(kEllipsis))), |
| 111 mirroring_context_(new MirroringContext()), | 114 mirroring_context_(new MirroringContext()), |
| 112 keyword_icon_(new views::ImageView()), | 115 keyword_icon_(new views::ImageView()), |
| 113 ALLOW_THIS_IN_INITIALIZER_LIST( | 116 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 114 animation_(new ui::SlideAnimation(this))) { | 117 animation_(new ui::SlideAnimation(this))) { |
| 115 CHECK_GE(model_index, 0); | 118 CHECK_GE(model_index, 0); |
| 116 if (default_icon_size_ == 0) { | 119 if (default_icon_size_ == 0) { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 } | 204 } |
| 202 | 205 |
| 203 void AutocompleteResultView::Invalidate() { | 206 void AutocompleteResultView::Invalidate() { |
| 204 keyword_icon_->SetImage(GetKeywordIcon()); | 207 keyword_icon_->SetImage(GetKeywordIcon()); |
| 205 SchedulePaint(); | 208 SchedulePaint(); |
| 206 } | 209 } |
| 207 | 210 |
| 208 gfx::Size AutocompleteResultView::GetPreferredSize() { | 211 gfx::Size AutocompleteResultView::GetPreferredSize() { |
| 209 return gfx::Size(0, std::max( | 212 return gfx::Size(0, std::max( |
| 210 default_icon_size_ + (kMinimumIconVerticalPadding * 2), | 213 default_icon_size_ + (kMinimumIconVerticalPadding * 2), |
| 211 GetTextHeight() + (kMinimumTextVerticalPadding * 2))); | 214 GetTextHeight() + (minimum_text_vertical_padding_ * 2))); |
| 212 } | 215 } |
| 213 | 216 |
| 214 //////////////////////////////////////////////////////////////////////////////// | 217 //////////////////////////////////////////////////////////////////////////////// |
| 215 // AutocompleteResultView, protected: | 218 // AutocompleteResultView, protected: |
| 216 | 219 |
| 220 AutocompleteResultView::ResultViewState | |
| 221 AutocompleteResultView::GetState() const { | |
| 222 if (model_->IsSelectedIndex(model_index_)) | |
| 223 return SELECTED; | |
| 224 return model_->IsHoveredIndex(model_index_) ? HOVERED : NORMAL; | |
| 225 } | |
| 226 | |
| 217 void AutocompleteResultView::PaintMatch(gfx::Canvas* canvas, | 227 void AutocompleteResultView::PaintMatch(gfx::Canvas* canvas, |
| 218 const AutocompleteMatch& match, | 228 const AutocompleteMatch& match, |
| 219 int x) { | 229 int x) { |
| 220 x = DrawString(canvas, match.contents, match.contents_class, false, x, | 230 x = DrawString(canvas, match.contents, match.contents_class, false, x, |
| 221 text_bounds_.y()); | 231 text_bounds_.y()); |
| 222 | 232 |
| 223 // Paint the description. | 233 // Paint the description. |
| 224 // TODO(pkasting): Because we paint in multiple separate pieces, we can wind | 234 // TODO(pkasting): Because we paint in multiple separate pieces, we can wind |
| 225 // up with no space even for an ellipsis for one or both of these pieces. | 235 // up with no space even for an ellipsis for one or both of these pieces. |
| 226 // Instead, we should paint the entire match as a single long string. This | 236 // Instead, we should paint the entire match as a single long string. This |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 237 | 247 |
| 238 DrawString(canvas, match.description, match.description_class, true, x, | 248 DrawString(canvas, match.description, match.description_class, true, x, |
| 239 text_bounds_.y()); | 249 text_bounds_.y()); |
| 240 } | 250 } |
| 241 } | 251 } |
| 242 | 252 |
| 243 int AutocompleteResultView::GetTextHeight() const { | 253 int AutocompleteResultView::GetTextHeight() const { |
| 244 return std::max(normal_font_.GetHeight(), bold_font_.GetHeight()); | 254 return std::max(normal_font_.GetHeight(), bold_font_.GetHeight()); |
| 245 } | 255 } |
| 246 | 256 |
| 257 void AutocompleteResultView::AdjustIconBounds(const AutocompleteMatch& match, | |
| 258 gfx::Rect* bounds) { | |
| 259 } | |
| 260 | |
| 247 // static | 261 // static |
| 248 bool AutocompleteResultView::SortRunsLogically(const RunData& lhs, | 262 bool AutocompleteResultView::SortRunsLogically(const RunData& lhs, |
| 249 const RunData& rhs) { | 263 const RunData& rhs) { |
| 250 return lhs.run_start < rhs.run_start; | 264 return lhs.run_start < rhs.run_start; |
| 251 } | 265 } |
| 252 | 266 |
| 253 // static | 267 // static |
| 254 bool AutocompleteResultView::SortRunsVisually(const RunData& lhs, | 268 bool AutocompleteResultView::SortRunsVisually(const RunData& lhs, |
| 255 const RunData& rhs) { | 269 const RunData& rhs) { |
| 256 return lhs.visual_order < rhs.visual_order; | 270 return lhs.visual_order < rhs.visual_order; |
| 257 } | 271 } |
| 258 | 272 |
| 259 // static | 273 // static |
| 260 int AutocompleteResultView::default_icon_size_ = 0; | 274 int AutocompleteResultView::default_icon_size_ = 0; |
| 261 | 275 |
| 262 AutocompleteResultView::ResultViewState | |
| 263 AutocompleteResultView::GetState() const { | |
| 264 if (model_->IsSelectedIndex(model_index_)) | |
| 265 return SELECTED; | |
| 266 return model_->IsHoveredIndex(model_index_) ? HOVERED : NORMAL; | |
| 267 } | |
| 268 | |
| 269 const SkBitmap* AutocompleteResultView::GetIcon() const { | 276 const SkBitmap* AutocompleteResultView::GetIcon() const { |
| 270 const SkBitmap* bitmap = model_->GetIconIfExtensionMatch(model_index_); | 277 const SkBitmap* bitmap = model_->GetIconIfExtensionMatch(model_index_); |
| 271 if (bitmap) | 278 if (bitmap) |
| 272 return bitmap; | 279 return bitmap; |
| 273 | 280 |
| 274 int icon = match_.starred ? | 281 int icon = match_.starred ? |
| 275 IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match_.type); | 282 IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match_.type); |
| 276 if (GetState() == SELECTED) { | 283 if (GetState() == SELECTED) { |
| 277 switch (icon) { | 284 switch (icon) { |
| 278 case IDR_OMNIBOX_EXTENSION_APP: | 285 case IDR_OMNIBOX_EXTENSION_APP: |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 531 } | 538 } |
| 532 } | 539 } |
| 533 | 540 |
| 534 // We couldn't draw anything. | 541 // We couldn't draw anything. |
| 535 runs->clear(); | 542 runs->clear(); |
| 536 } | 543 } |
| 537 | 544 |
| 538 void AutocompleteResultView::Layout() { | 545 void AutocompleteResultView::Layout() { |
| 539 const SkBitmap* icon = GetIcon(); | 546 const SkBitmap* icon = GetIcon(); |
| 540 | 547 |
| 541 icon_bounds_.SetRect(LocationBarView::kEdgeItemPadding + | 548 icon_bounds_.SetRect( |
| 542 ((icon->width() == default_icon_size_) ? | 549 edge_item_padding_ + ((icon->width() == default_icon_size_) ? 0 : |
|
Peter Kasting
2012/05/07 21:03:12
Nit: Wrap these lines as they were before (maintai
Jói
2012/05/10 18:33:07
Went one step further and separated it out as a te
| |
| 543 0 : LocationBarView::kIconInternalPadding), | 550 LocationBarView::kIconInternalPadding), |
| 544 (height() - icon->height()) / 2, icon->width(), icon->height()); | 551 (height() - icon->height()) / 2, icon->width(), icon->height()); |
| 545 | 552 |
| 546 int text_x = LocationBarView::kEdgeItemPadding + default_icon_size_ + | 553 int text_x = edge_item_padding_ + default_icon_size_ + item_padding_; |
| 547 LocationBarView::kItemPadding; | |
| 548 int text_height = GetTextHeight(); | 554 int text_height = GetTextHeight(); |
| 549 int text_width; | 555 int text_width; |
| 550 | 556 |
| 551 if (match_.associated_keyword.get()) { | 557 if (match_.associated_keyword.get()) { |
| 552 const int kw_collapsed_size = keyword_icon_->width() + | 558 const int kw_collapsed_size = keyword_icon_->width() + |
| 553 LocationBarView::kEdgeItemPadding; | 559 edge_item_padding_; |
| 554 const int max_kw_x = width() - kw_collapsed_size; | 560 const int max_kw_x = width() - kw_collapsed_size; |
| 555 const int kw_x = animation_->CurrentValueBetween(max_kw_x, | 561 const int kw_x = animation_->CurrentValueBetween(max_kw_x, |
| 556 LocationBarView::kEdgeItemPadding); | 562 edge_item_padding_); |
| 557 const int kw_text_x = kw_x + keyword_icon_->width() + | 563 const int kw_text_x = kw_x + keyword_icon_->width() + item_padding_; |
| 558 LocationBarView::kItemPadding; | |
| 559 | 564 |
| 560 text_width = kw_x - text_x - LocationBarView::kItemPadding; | 565 text_width = kw_x - text_x - item_padding_; |
| 561 keyword_text_bounds_.SetRect(kw_text_x, 0, std::max( | 566 keyword_text_bounds_.SetRect(kw_text_x, 0, std::max( |
| 562 width() - kw_text_x - LocationBarView::kEdgeItemPadding, 0), | 567 width() - kw_text_x - edge_item_padding_, 0), |
| 563 text_height); | 568 text_height); |
| 564 keyword_icon_->SetPosition(gfx::Point(kw_x, | 569 keyword_icon_->SetPosition(gfx::Point(kw_x, |
| 565 (height() - keyword_icon_->height()) / 2)); | 570 (height() - keyword_icon_->height()) / 2)); |
| 566 } else { | 571 } else { |
| 567 text_width = width() - text_x - LocationBarView::kEdgeItemPadding; | 572 text_width = width() - text_x - edge_item_padding_; |
| 568 } | 573 } |
| 569 | 574 |
| 570 text_bounds_.SetRect(text_x, std::max(0, (height() - text_height) / 2), | 575 text_bounds_.SetRect(text_x, std::max(0, (height() - text_height) / 2), |
| 571 std::max(text_width, 0), text_height); | 576 std::max(text_width, 0), text_height); |
| 572 } | 577 } |
| 573 | 578 |
| 574 void AutocompleteResultView::OnBoundsChanged( | 579 void AutocompleteResultView::OnBoundsChanged( |
| 575 const gfx::Rect& previous_bounds) { | 580 const gfx::Rect& previous_bounds) { |
| 576 animation_->SetSlideDuration(width() / 4); | 581 animation_->SetSlideDuration(width() / 4); |
| 577 } | 582 } |
| 578 | 583 |
| 579 void AutocompleteResultView::OnPaint(gfx::Canvas* canvas) { | 584 void AutocompleteResultView::OnPaint(gfx::Canvas* canvas) { |
| 580 const ResultViewState state = GetState(); | 585 const ResultViewState state = GetState(); |
| 581 if (state != NORMAL) | 586 if (state != NORMAL) |
| 582 canvas->DrawColor(GetColor(state, BACKGROUND)); | 587 canvas->DrawColor(GetColor(state, BACKGROUND)); |
| 583 | 588 |
| 584 if (!match_.associated_keyword.get() || | 589 if (!match_.associated_keyword.get() || |
| 585 keyword_icon_->x() > icon_bounds_.right()) { | 590 keyword_icon_->x() > icon_bounds_.right()) { |
| 586 // Paint the icon. | 591 // Paint the icon. |
| 587 canvas->DrawBitmapInt(*GetIcon(), GetMirroredXForRect(icon_bounds_), | 592 AdjustIconBounds(match_, &icon_bounds_); |
| 588 icon_bounds_.y()); | 593 canvas->DrawBitmapInt( |
|
Peter Kasting
2012/05/07 21:03:12
Nit: Better than either old or new wrapping would
Jói
2012/05/10 18:33:07
Done.
| |
| 594 *GetIcon(), GetMirroredXForRect(icon_bounds_), icon_bounds_.y()); | |
| 589 | 595 |
| 590 // Paint the text. | 596 // Paint the text. |
| 591 int x = GetMirroredXForRect(text_bounds_); | 597 int x = GetMirroredXForRect(text_bounds_); |
| 592 mirroring_context_->Initialize(x, text_bounds_.width()); | 598 mirroring_context_->Initialize(x, text_bounds_.width()); |
| 593 PaintMatch(canvas, match_, x); | 599 PaintMatch(canvas, match_, x); |
| 594 } | 600 } |
| 595 | 601 |
| 596 if (match_.associated_keyword.get()) { | 602 if (match_.associated_keyword.get()) { |
| 597 // Paint the keyword text. | 603 // Paint the keyword text. |
| 598 int x = GetMirroredXForRect(keyword_text_bounds_); | 604 int x = GetMirroredXForRect(keyword_text_bounds_); |
| 599 mirroring_context_->Initialize(x, keyword_text_bounds_.width()); | 605 mirroring_context_->Initialize(x, keyword_text_bounds_.width()); |
| 600 PaintMatch(canvas, *match_.associated_keyword.get(), x); | 606 PaintMatch(canvas, *match_.associated_keyword.get(), x); |
| 601 } | 607 } |
| 602 } | 608 } |
| 603 | 609 |
| 604 void AutocompleteResultView::AnimationProgressed( | 610 void AutocompleteResultView::AnimationProgressed( |
| 605 const ui::Animation* animation) { | 611 const ui::Animation* animation) { |
| 606 Layout(); | 612 Layout(); |
| 607 SchedulePaint(); | 613 SchedulePaint(); |
| 608 } | 614 } |
| 609 | 615 |
| OLD | NEW |