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

Side by Side Diff: chrome/browser/ui/views/autocomplete/autocomplete_popup_contents_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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 #include "chrome/browser/ui/views/autocomplete/autocomplete_popup_contents_view. h" 5 #include "chrome/browser/ui/views/autocomplete/autocomplete_popup_contents_view. h"
6 6
7 #if defined(OS_WIN) 7 #if defined(OS_WIN)
8 #include <commctrl.h> 8 #include <commctrl.h>
9 #include <dwmapi.h> 9 #include <dwmapi.h>
10 #include <objidl.h> 10 #include <objidl.h>
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 #include "base/win/scoped_gdi_object.h" 42 #include "base/win/scoped_gdi_object.h"
43 #if !defined(USE_AURA) 43 #if !defined(USE_AURA)
44 #include "ui/views/widget/native_widget_win.h" 44 #include "ui/views/widget/native_widget_win.h"
45 #endif 45 #endif
46 #endif 46 #endif
47 47
48 namespace { 48 namespace {
49 49
50 const SkAlpha kGlassPopupAlpha = 240; 50 const SkAlpha kGlassPopupAlpha = 240;
51 const SkAlpha kOpaquePopupAlpha = 255; 51 const SkAlpha kOpaquePopupAlpha = 255;
52
52 // The size delta between the font used for the edit and the result rows. Passed 53 // The size delta between the font used for the edit and the result rows. Passed
53 // to gfx::Font::DeriveFont. 54 // to gfx::Font::DeriveFont.
54 #if defined(OS_CHROMEOS) 55 #if defined(OS_CHROMEOS)
55 // Don't adjust the size on Chrome OS (http://crbug.com/61433). 56 // Don't adjust the size on Chrome OS (http://crbug.com/61433).
56 const int kEditFontAdjust = 0; 57 const int kEditFontAdjust = 0;
57 #else 58 #else
58 const int kEditFontAdjust = -1; 59 const int kEditFontAdjust = -1;
59 #endif 60 #endif
60 61
61 // Horizontal padding between the buttons on the opt in promo. 62 // Horizontal padding between the buttons on the opt in promo.
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 ALLOW_THIS_IN_INITIALIZER_LIST(size_animation_(this)) { 226 ALLOW_THIS_IN_INITIALIZER_LIST(size_animation_(this)) {
226 // The following little dance is required because set_border() requires a 227 // The following little dance is required because set_border() requires a
227 // pointer to a non-const object. 228 // pointer to a non-const object.
228 views::BubbleBorder* bubble_border = 229 views::BubbleBorder* bubble_border =
229 new views::BubbleBorder(views::BubbleBorder::NONE, 230 new views::BubbleBorder(views::BubbleBorder::NONE,
230 views::BubbleBorder::NO_SHADOW); 231 views::BubbleBorder::NO_SHADOW);
231 bubble_border_ = bubble_border; 232 bubble_border_ = bubble_border;
232 set_border(bubble_border); 233 set_border(bubble_border);
233 // The contents is owned by the LocationBarView. 234 // The contents is owned by the LocationBarView.
234 set_parent_owned(false); 235 set_parent_owned(false);
236
237 for (size_t i = 0; i < AutocompleteResult::kMaxMatches; ++i) {
238 AutocompleteResultView* result_view =
239 CreateResultView(this, i, result_font_, result_bold_font_);
240 result_view->SetVisible(false);
241 AddChildViewAt(result_view, static_cast<int>(i));
242 }
235 } 243 }
236 244
237 AutocompletePopupContentsView::~AutocompletePopupContentsView() { 245 AutocompletePopupContentsView::~AutocompletePopupContentsView() {
238 // We don't need to do anything with |popup_| here. The OS either has already 246 // We don't need to do anything with |popup_| here. The OS either has already
239 // closed the window, in which case it's been deleted, or it will soon, in 247 // closed the window, in which case it's been deleted, or it will soon, in
240 // which case there's nothing we need to do. 248 // which case there's nothing we need to do.
241 } 249 }
242 250
243 gfx::Rect AutocompletePopupContentsView::GetPopupBounds() const { 251 gfx::Rect AutocompletePopupContentsView::GetPopupBounds() const {
244 if (!size_animation_.is_animating()) 252 if (!size_animation_.is_animating())
(...skipping 25 matching lines...) Expand all
270 } 278 }
271 279
272 //////////////////////////////////////////////////////////////////////////////// 280 ////////////////////////////////////////////////////////////////////////////////
273 // AutocompletePopupContentsView, AutocompletePopupView overrides: 281 // AutocompletePopupContentsView, AutocompletePopupView overrides:
274 282
275 bool AutocompletePopupContentsView::IsOpen() const { 283 bool AutocompletePopupContentsView::IsOpen() const {
276 return (popup_ != NULL); 284 return (popup_ != NULL);
277 } 285 }
278 286
279 void AutocompletePopupContentsView::InvalidateLine(size_t line) { 287 void AutocompletePopupContentsView::InvalidateLine(size_t line) {
280 child_at(static_cast<int>(line))->SchedulePaint(); 288 AutocompleteResultView* result = static_cast<AutocompleteResultView*>(
289 child_at(static_cast<int>(line)));
290 result->Invalidate();
291
292 if (HasMatchAt(line) && GetMatchAtIndex(line).associated_keyword.get()) {
293 result->ShowKeyword(IsSelectedIndex(line) &&
294 model_->selected_line_state() == AutocompletePopupModel::KEYWORD);
295 }
281 } 296 }
282 297
283 void AutocompletePopupContentsView::UpdatePopupAppearance() { 298 void AutocompletePopupContentsView::UpdatePopupAppearance() {
284 if (model_->result().empty()) { 299 if (model_->result().empty()) {
285 // No matches, close any existing popup. 300 // No matches, close any existing popup.
286 if (popup_ != NULL) { 301 if (popup_ != NULL) {
287 size_animation_.Stop(); 302 size_animation_.Stop();
303
288 // NOTE: Do NOT use CloseNow() here, as we may be deep in a callstack 304 // NOTE: Do NOT use CloseNow() here, as we may be deep in a callstack
289 // triggered by the popup receiving a message (e.g. LBUTTONUP), and 305 // triggered by the popup receiving a message (e.g. LBUTTONUP), and
290 // destroying the popup would cause us to read garbage when we unwind back 306 // destroying the popup would cause us to read garbage when we unwind back
291 // to that level. 307 // to that level.
292 popup_->Close(); // This will eventually delete the popup. 308 popup_->Close(); // This will eventually delete the popup.
293 popup_.reset(); 309 popup_.reset();
294 } 310 }
295 return; 311 return;
296 } 312 }
297 313
298 // Update the match cached by each row, in the process of doing so make sure 314 // Update the match cached by each row, in the process of doing so make sure
299 // we have enough row views. 315 // we have enough row views.
300 size_t child_rv_count = child_count(); 316 size_t child_rv_count = child_count();
301 if (opt_in_view_) { 317 if (opt_in_view_) {
302 DCHECK_GT(child_rv_count, 0u); 318 DCHECK_GT(child_rv_count, 0u);
303 child_rv_count--; 319 child_rv_count--;
304 } 320 }
305 for (size_t i = 0; i < model_->result().size(); ++i) { 321 const size_t result_size = model_->result().size();
306 AutocompleteResultView* result_view; 322 for (size_t i = 0; i < result_size; ++i) {
307 if (i >= child_rv_count) { 323 AutocompleteResultView* view = static_cast<AutocompleteResultView*>(
308 result_view = 324 child_at(i));
309 CreateResultView(this, i, result_font_, result_bold_font_); 325 view->SetMatch(GetMatchAtIndex(i));
310 AddChildViewAt(result_view, static_cast<int>(i)); 326 view->SetVisible(true);
311 } else {
312 result_view = static_cast<AutocompleteResultView*>(child_at(i));
313 result_view->SetVisible(true);
314 }
315 result_view->SetMatch(GetMatchAtIndex(i));
316 } 327 }
317 for (size_t i = model_->result().size(); i < child_rv_count; ++i) 328 for (size_t i = result_size; i < child_rv_count; ++i)
318 child_at(i)->SetVisible(false); 329 child_at(i)->SetVisible(false);
319 330
320 PromoCounter* counter = profile_->GetInstantPromoCounter(); 331 PromoCounter* counter = profile_->GetInstantPromoCounter();
321 if (!opt_in_view_ && counter && counter->ShouldShow(base::Time::Now())) { 332 if (!opt_in_view_ && counter && counter->ShouldShow(base::Time::Now())) {
322 opt_in_view_ = new InstantOptInView(this, result_bold_font_, result_font_); 333 opt_in_view_ = new InstantOptInView(this, result_bold_font_, result_font_);
323 AddChildView(opt_in_view_); 334 AddChildView(opt_in_view_);
324 } else if (opt_in_view_ && (!counter || 335 } else if (opt_in_view_ && (!counter ||
325 !counter->ShouldShow(base::Time::Now()))) { 336 !counter->ShouldShow(base::Time::Now()))) {
326 delete opt_in_view_; 337 delete opt_in_view_;
327 opt_in_view_ = NULL; 338 opt_in_view_ = NULL;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 } 390 }
380 391
381 void AutocompletePopupContentsView::OnDragCanceled() { 392 void AutocompletePopupContentsView::OnDragCanceled() {
382 ignore_mouse_drag_ = true; 393 ignore_mouse_drag_ = true;
383 } 394 }
384 395
385 //////////////////////////////////////////////////////////////////////////////// 396 ////////////////////////////////////////////////////////////////////////////////
386 // AutocompletePopupContentsView, AutocompleteResultViewModel implementation: 397 // AutocompletePopupContentsView, AutocompleteResultViewModel implementation:
387 398
388 bool AutocompletePopupContentsView::IsSelectedIndex(size_t index) const { 399 bool AutocompletePopupContentsView::IsSelectedIndex(size_t index) const {
389 return HasMatchAt(index) ? index == model_->selected_line() : false; 400 return index == model_->selected_line();
390 } 401 }
391 402
392 bool AutocompletePopupContentsView::IsHoveredIndex(size_t index) const { 403 bool AutocompletePopupContentsView::IsHoveredIndex(size_t index) const {
393 return HasMatchAt(index) ? index == model_->hovered_line() : false; 404 return index == model_->hovered_line();
394 } 405 }
395 406
396 const SkBitmap* AutocompletePopupContentsView::GetIconIfExtensionMatch( 407 const SkBitmap* AutocompletePopupContentsView::GetIconIfExtensionMatch(
397 size_t index) const { 408 size_t index) const {
398 if (!HasMatchAt(index)) 409 if (!HasMatchAt(index))
399 return NULL; 410 return NULL;
400 return model_->GetIconIfExtensionMatch(GetMatchAtIndex(index)); 411 return model_->GetIconIfExtensionMatch(GetMatchAtIndex(index));
401 } 412 }
402 413
403 //////////////////////////////////////////////////////////////////////////////// 414 ////////////////////////////////////////////////////////////////////////////////
(...skipping 15 matching lines...) Expand all
419 // Size our children to the available content area. 430 // Size our children to the available content area.
420 LayoutChildren(); 431 LayoutChildren();
421 432
422 // We need to manually schedule a paint here since we are a layered window and 433 // We need to manually schedule a paint here since we are a layered window and
423 // won't implicitly require painting until we ask for one. 434 // won't implicitly require painting until we ask for one.
424 SchedulePaint(); 435 SchedulePaint();
425 } 436 }
426 437
427 views::View* AutocompletePopupContentsView::GetEventHandlerForPoint( 438 views::View* AutocompletePopupContentsView::GetEventHandlerForPoint(
428 const gfx::Point& point) { 439 const gfx::Point& point) {
429 // If there is no opt in view, then we want all mouse events. Otherwise let 440 // If there is no opt in view then we want all mouse events. Otherwise, let
430 // any descendants of the opt-in view get mouse events. 441 // any descendants of the opt-in view get mouse events.
431 if (!opt_in_view_) 442 if (!opt_in_view_)
432 return this; 443 return this;
433 444
434 views::View* child = views::View::GetEventHandlerForPoint(point); 445 views::View* child = views::View::GetEventHandlerForPoint(point);
435 views::View* ancestor = child; 446 views::View* ancestor = child;
436 while (ancestor && ancestor != opt_in_view_) 447 while (ancestor && ancestor != opt_in_view_)
437 ancestor = ancestor->parent(); 448 ancestor = ancestor->parent();
438 return ancestor ? child : this; 449 return ancestor ? child : this;
439 } 450 }
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 void AutocompletePopupContentsView::OpenIndex( 641 void AutocompletePopupContentsView::OpenIndex(
631 size_t index, 642 size_t index,
632 WindowOpenDisposition disposition) { 643 WindowOpenDisposition disposition) {
633 if (!HasMatchAt(index)) 644 if (!HasMatchAt(index))
634 return; 645 return;
635 646
636 // OpenMatch() may close the popup, which will clear the result set and, by 647 // OpenMatch() may close the popup, which will clear the result set and, by
637 // extension, |match| and its contents. So copy the relevant match out to 648 // extension, |match| and its contents. So copy the relevant match out to
638 // make sure it stays alive until the call completes. 649 // make sure it stays alive until the call completes.
639 AutocompleteMatch match = model_->result().match_at(index); 650 AutocompleteMatch match = model_->result().match_at(index);
640 string16 keyword;
641 const bool is_keyword_hint = model_->GetKeywordForMatch(match, &keyword);
642 omnibox_view_->OpenMatch(match, disposition, GURL(), index, 651 omnibox_view_->OpenMatch(match, disposition, GURL(), index,
643 is_keyword_hint ? string16() : keyword); 652 match.keyword);
644 } 653 }
645 654
646 size_t AutocompletePopupContentsView::GetIndexForPoint( 655 size_t AutocompletePopupContentsView::GetIndexForPoint(
647 const gfx::Point& point) { 656 const gfx::Point& point) {
648 if (!HitTest(point)) 657 if (!HitTest(point))
649 return AutocompletePopupModel::kNoMatch; 658 return AutocompletePopupModel::kNoMatch;
650 659
651 int nb_match = model_->result().size(); 660 int nb_match = model_->result().size();
652 DCHECK(nb_match <= child_count()); 661 DCHECK(nb_match <= child_count());
653 for (int i = 0; i < nb_match; ++i) { 662 for (int i = 0; i < nb_match; ++i) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
688 opt_in_view_ = NULL; 697 opt_in_view_ = NULL;
689 PromoCounter* counter = profile_->GetInstantPromoCounter(); 698 PromoCounter* counter = profile_->GetInstantPromoCounter();
690 DCHECK(counter); 699 DCHECK(counter);
691 counter->Hide(); 700 counter->Hide();
692 if (opt_in) { 701 if (opt_in) {
693 browser::ShowInstantConfirmDialogIfNecessary( 702 browser::ShowInstantConfirmDialogIfNecessary(
694 location_bar_->GetWidget()->GetNativeWindow(), profile_); 703 location_bar_->GetWidget()->GetNativeWindow(), profile_);
695 } 704 }
696 UpdatePopupAppearance(); 705 UpdatePopupAppearance();
697 } 706 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698