Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(270)

Side by Side Diff: chrome/browser/ui/views/autocomplete/autocomplete_result_view.cc

Issue 6731036: Enabled pressing TAB to cycle through the Omnibox results. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/autocomplete/autocomplete_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/ui/views/autocomplete/autocomplete_result_view_model.h" 18 #include "chrome/browser/ui/views/autocomplete/autocomplete_result_view_model.h"
18 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" 19 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
19 #include "grit/generated_resources.h" 20 #include "grit/generated_resources.h"
20 #include "grit/theme_resources.h" 21 #include "grit/theme_resources.h"
21 #include "ui/base/l10n/l10n_util.h" 22 #include "ui/base/l10n/l10n_util.h"
22 #include "ui/base/resource/resource_bundle.h" 23 #include "ui/base/resource/resource_bundle.h"
23 #include "ui/base/text/text_elider.h" 24 #include "ui/base/text/text_elider.h"
24 #include "ui/gfx/canvas_skia.h" 25 #include "ui/gfx/canvas_skia.h"
25 #include "ui/gfx/color_utils.h" 26 #include "ui/gfx/color_utils.h"
26 #include "ui/gfx/native_theme.h" 27 #include "ui/gfx/native_theme.h"
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 AutocompleteResultView::AutocompleteResultView( 106 AutocompleteResultView::AutocompleteResultView(
106 AutocompleteResultViewModel* model, 107 AutocompleteResultViewModel* model,
107 int model_index, 108 int model_index,
108 const gfx::Font& font, 109 const gfx::Font& font,
109 const gfx::Font& bold_font) 110 const gfx::Font& bold_font)
110 : model_(model), 111 : model_(model),
111 model_index_(model_index), 112 model_index_(model_index),
112 normal_font_(font), 113 normal_font_(font),
113 bold_font_(bold_font), 114 bold_font_(bold_font),
114 ellipsis_width_(font.GetStringWidth(string16(kEllipsis))), 115 ellipsis_width_(font.GetStringWidth(string16(kEllipsis))),
115 mirroring_context_(new MirroringContext()) { 116 mirroring_context_(new MirroringContext()),
117 keyword_icon_(new views::ImageView()),
118 ALLOW_THIS_IN_INITIALIZER_LIST(
119 animation_(new ui::SlideAnimation(this))) {
116 CHECK_GE(model_index, 0); 120 CHECK_GE(model_index, 0);
117 if (default_icon_size_ == 0) { 121 if (default_icon_size_ == 0) {
118 default_icon_size_ = ResourceBundle::GetSharedInstance().GetBitmapNamed( 122 default_icon_size_ = ResourceBundle::GetSharedInstance().GetBitmapNamed(
119 AutocompleteMatch::TypeToIcon(AutocompleteMatch::URL_WHAT_YOU_TYPED))-> 123 AutocompleteMatch::TypeToIcon(AutocompleteMatch::URL_WHAT_YOU_TYPED))->
120 width(); 124 width();
121 } 125 }
126 keyword_icon_->set_parent_owned(false);
127 keyword_icon_->EnableCanvasFlippingForRTLUI(true);
128 keyword_icon_->SetImage(GetKeywordIcon());
129 keyword_icon_->SizeToPreferredSize();
122 } 130 }
123 131
124 AutocompleteResultView::~AutocompleteResultView() { 132 AutocompleteResultView::~AutocompleteResultView() {
125 } 133 }
126 134
127 // static 135 // static
128 SkColor AutocompleteResultView::GetColor(ResultViewState state, 136 SkColor AutocompleteResultView::GetColor(ResultViewState state,
129 ColorKind kind) { 137 ColorKind kind) {
130 static bool initialized = false; 138 static bool initialized = false;
131 static SkColor colors[NUM_STATES][NUM_KINDS]; 139 static SkColor colors[NUM_STATES][NUM_KINDS];
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 colors[i][BACKGROUND]); 179 colors[i][BACKGROUND]);
172 } 180 }
173 initialized = true; 181 initialized = true;
174 } 182 }
175 183
176 return colors[state][kind]; 184 return colors[state][kind];
177 } 185 }
178 186
179 void AutocompleteResultView::SetMatch(const AutocompleteMatch& match) { 187 void AutocompleteResultView::SetMatch(const AutocompleteMatch& match) {
180 match_ = match; 188 match_ = match;
189 animation_->Reset();
190
191 if (match.associated_keyword.get()) {
192 keyword_icon_->SetImage(GetKeywordIcon());
193
194 if (!keyword_icon_->parent())
195 AddChildView(keyword_icon_.get());
196 } else if (keyword_icon_->parent()) {
197 RemoveChildView(keyword_icon_.get());
198 }
199
181 Layout(); 200 Layout();
182 } 201 }
183 202
203 void AutocompleteResultView::ShowKeyword(bool show_keyword) {
204 if (show_keyword)
205 animation_->Show();
206 else
207 animation_->Hide();
208 }
209
210 void AutocompleteResultView::Invalidate() {
211 keyword_icon_->SetImage(GetKeywordIcon());
212 SchedulePaint();
213 }
214
215 gfx::Size AutocompleteResultView::GetPreferredSize() {
216 return gfx::Size(0, std::max(
217 default_icon_size_ + (kMinimumIconVerticalPadding * 2),
218 GetTextHeight() + (kMinimumTextVerticalPadding * 2)));
219 }
220
184 //////////////////////////////////////////////////////////////////////////////// 221 ////////////////////////////////////////////////////////////////////////////////
185 // AutocompleteResultView, protected: 222 // AutocompleteResultView, protected:
186 223
187 void AutocompleteResultView::PaintMatch(gfx::Canvas* canvas, 224 void AutocompleteResultView::PaintMatch(gfx::Canvas* canvas,
188 const AutocompleteMatch& match, 225 const AutocompleteMatch& match,
189 int x) { 226 int x) {
190 x = DrawString(canvas, match.contents, match.contents_class, false, x, 227 x = DrawString(canvas, match.contents, match.contents_class, false, x,
191 text_bounds_.y()); 228 text_bounds_.y());
192 229
193 // Paint the description. 230 // Paint the description.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 return model_->IsHoveredIndex(model_index_) ? HOVERED : NORMAL; 273 return model_->IsHoveredIndex(model_index_) ? HOVERED : NORMAL;
237 } 274 }
238 275
239 const SkBitmap* AutocompleteResultView::GetIcon() const { 276 const SkBitmap* AutocompleteResultView::GetIcon() const {
240 const SkBitmap* bitmap = model_->GetIconIfExtensionMatch(model_index_); 277 const SkBitmap* bitmap = model_->GetIconIfExtensionMatch(model_index_);
241 if (bitmap) 278 if (bitmap)
242 return bitmap; 279 return bitmap;
243 280
244 int icon = match_.starred ? 281 int icon = match_.starred ?
245 IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match_.type); 282 IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match_.type);
246 if (model_->IsSelectedIndex(model_index_)) { 283 if (GetState() == SELECTED) {
247 switch (icon) { 284 switch (icon) {
248 case IDR_OMNIBOX_EXTENSION_APP: 285 case IDR_OMNIBOX_EXTENSION_APP:
249 icon = IDR_OMNIBOX_EXTENSION_APP_SELECTED; 286 icon = IDR_OMNIBOX_EXTENSION_APP_SELECTED;
250 break; 287 break;
251 case IDR_OMNIBOX_HTTP: 288 case IDR_OMNIBOX_HTTP:
252 icon = IDR_OMNIBOX_HTTP_SELECTED; 289 icon = IDR_OMNIBOX_HTTP_SELECTED;
253 break; 290 break;
254 case IDR_OMNIBOX_HISTORY: 291 case IDR_OMNIBOX_HISTORY:
255 icon = IDR_OMNIBOX_HISTORY_SELECTED; 292 icon = IDR_OMNIBOX_HISTORY_SELECTED;
256 break; 293 break;
257 case IDR_OMNIBOX_SEARCH: 294 case IDR_OMNIBOX_SEARCH:
258 icon = IDR_OMNIBOX_SEARCH_SELECTED; 295 icon = IDR_OMNIBOX_SEARCH_SELECTED;
259 break; 296 break;
260 case IDR_OMNIBOX_STAR: 297 case IDR_OMNIBOX_STAR:
261 icon = IDR_OMNIBOX_STAR_SELECTED; 298 icon = IDR_OMNIBOX_STAR_SELECTED;
262 break; 299 break;
263 default: 300 default:
264 NOTREACHED(); 301 NOTREACHED();
265 break; 302 break;
266 } 303 }
267 } 304 }
268 return ResourceBundle::GetSharedInstance().GetBitmapNamed(icon); 305 return ResourceBundle::GetSharedInstance().GetBitmapNamed(icon);
269 } 306 }
270 307
308 const SkBitmap* AutocompleteResultView::GetKeywordIcon() const {
309 // 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.
311 return ResourceBundle::GetSharedInstance().GetBitmapNamed(
312 (GetState() == SELECTED) ? IDR_OMNIBOX_TTS_SELECTED : IDR_OMNIBOX_TTS);
313 }
314
271 int AutocompleteResultView::DrawString( 315 int AutocompleteResultView::DrawString(
272 gfx::Canvas* canvas, 316 gfx::Canvas* canvas,
273 const string16& text, 317 const string16& text,
274 const ACMatchClassifications& classifications, 318 const ACMatchClassifications& classifications,
275 bool force_dim, 319 bool force_dim,
276 int x, 320 int x,
277 int y) { 321 int y) {
278 if (text.empty()) 322 if (text.empty())
279 return x; 323 return x;
280 324
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 // ellipsis we'll append to it, or 535 // ellipsis we'll append to it, or
492 // * It is also bold, in which case we don't want to fall back 536 // * It is also bold, in which case we don't want to fall back
493 // to a normal ellipsis anyway (see comment above). 537 // to a normal ellipsis anyway (see comment above).
494 } 538 }
495 } 539 }
496 540
497 // We couldn't draw anything. 541 // We couldn't draw anything.
498 runs->clear(); 542 runs->clear();
499 } 543 }
500 544
501 gfx::Size AutocompleteResultView::GetPreferredSize() {
502 return gfx::Size(0, std::max(
503 default_icon_size_ + (kMinimumIconVerticalPadding * 2),
504 GetTextHeight() + (kMinimumTextVerticalPadding * 2)));
505 }
506
507 void AutocompleteResultView::Layout() { 545 void AutocompleteResultView::Layout() {
508 const SkBitmap* icon = GetIcon(); 546 const SkBitmap* icon = GetIcon();
547
509 icon_bounds_.SetRect(LocationBarView::kEdgeItemPadding + 548 icon_bounds_.SetRect(LocationBarView::kEdgeItemPadding +
510 ((icon->width() == default_icon_size_) ? 549 ((icon->width() == default_icon_size_) ?
511 0 : LocationBarView::kIconInternalPadding), 550 0 : LocationBarView::kIconInternalPadding),
512 (height() - icon->height()) / 2, icon->width(), icon->height()); 551 (height() - icon->height()) / 2, icon->width(), icon->height());
513 552
514 int text_x = LocationBarView::kEdgeItemPadding + default_icon_size_ + 553 int text_x = LocationBarView::kEdgeItemPadding + default_icon_size_ +
515 LocationBarView::kItemPadding; 554 LocationBarView::kItemPadding;
516 int text_height = GetTextHeight(); 555 int text_height = GetTextHeight();
556 int text_width;
557
558 if (match_.associated_keyword.get()) {
559 const int kw_collapsed_size = keyword_icon_->width() +
560 LocationBarView::kEdgeItemPadding;
561 const int max_kw_x = width() - kw_collapsed_size;
562 const int kw_x = animation_->CurrentValueBetween(max_kw_x,
563 LocationBarView::kEdgeItemPadding);
564 const int kw_text_x = kw_x + keyword_icon_->width() +
565 LocationBarView::kItemPadding;
566
567 text_width = kw_x - text_x - LocationBarView::kItemPadding;
568 keyword_text_bounds_.SetRect(kw_text_x, 0, std::max(
569 width() - kw_text_x - LocationBarView::kEdgeItemPadding, 0),
570 text_height);
571 keyword_icon_->SetPosition(gfx::Point(kw_x,
572 (height() - keyword_icon_->height()) / 2));
573 } else {
574 text_width = width() - text_x - LocationBarView::kEdgeItemPadding;
575 }
576
517 text_bounds_.SetRect(text_x, std::max(0, (height() - text_height) / 2), 577 text_bounds_.SetRect(text_x, std::max(0, (height() - text_height) / 2),
518 std::max(bounds().width() - text_x - LocationBarView::kEdgeItemPadding, 578 std::max(text_width, 0), text_height);
519 0), text_height); 579 }
580
581 void AutocompleteResultView::OnBoundsChanged(
582 const gfx::Rect& previous_bounds) {
583 animation_->SetSlideDuration(width() / 4);
520 } 584 }
521 585
522 void AutocompleteResultView::OnPaint(gfx::Canvas* canvas) { 586 void AutocompleteResultView::OnPaint(gfx::Canvas* canvas) {
523 const ResultViewState state = GetState(); 587 const ResultViewState state = GetState();
524 if (state != NORMAL) 588 if (state != NORMAL)
525 canvas->GetSkCanvas()->drawColor(GetColor(state, BACKGROUND)); 589 canvas->GetSkCanvas()->drawColor(GetColor(state, BACKGROUND));
526 590
527 // Paint the icon. 591 if (!match_.associated_keyword.get() ||
528 canvas->DrawBitmapInt(*GetIcon(), GetMirroredXForRect(icon_bounds_), 592 keyword_icon_->x() > icon_bounds_.right()) {
529 icon_bounds_.y()); 593 // Paint the icon.
594 canvas->DrawBitmapInt(*GetIcon(), GetMirroredXForRect(icon_bounds_),
595 icon_bounds_.y());
530 596
531 // Paint the text. 597 // Paint the text.
532 int x = GetMirroredXForRect(text_bounds_); 598 int x = GetMirroredXForRect(text_bounds_);
533 mirroring_context_->Initialize(x, text_bounds_.width()); 599 mirroring_context_->Initialize(x, text_bounds_.width());
534 PaintMatch(canvas, match_, x); 600 PaintMatch(canvas, match_, x);
601 }
602
603 if (match_.associated_keyword.get()) {
604 // Paint the keyword text.
605 int x = GetMirroredXForRect(keyword_text_bounds_);
606 mirroring_context_->Initialize(x, keyword_text_bounds_.width());
607 PaintMatch(canvas, *match_.associated_keyword.get(), x);
608 }
535 } 609 }
610
611 void AutocompleteResultView::AnimationProgressed(
612 const ui::Animation* animation) {
613 Layout();
614 SchedulePaint();
615 }
616
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698