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

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 9 years, 1 month 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 "views/widget/native_widget_win.h" 44 #include "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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 ignore_mouse_drag_(false), 225 ignore_mouse_drag_(false),
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 bubble_border_ = bubble_border; 231 bubble_border_ = bubble_border;
231 set_border(bubble_border); 232 set_border(bubble_border);
232 // The contents is owned by the LocationBarView. 233 // The contents is owned by the LocationBarView.
233 set_parent_owned(false); 234 set_parent_owned(false);
235
236 for (size_t i = 0; i < AutocompleteResult::kMaxMatches; ++i) {
237 AutocompleteResultView* result_view =
238 CreateResultView(this, i, result_font_, result_bold_font_);
239 result_view->SetVisible(false);
240 result_view->set_popup_model(model_.get());
241 AddChildViewAt(result_view, static_cast<int>(i));
242 }
234 } 243 }
235 244
236 AutocompletePopupContentsView::~AutocompletePopupContentsView() { 245 AutocompletePopupContentsView::~AutocompletePopupContentsView() {
237 // 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
238 // 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
239 // which case there's nothing we need to do. 248 // which case there's nothing we need to do.
240 } 249 }
241 250
242 gfx::Rect AutocompletePopupContentsView::GetPopupBounds() const { 251 gfx::Rect AutocompletePopupContentsView::GetPopupBounds() const {
243 if (!size_animation_.is_animating()) 252 if (!size_animation_.is_animating())
(...skipping 11 matching lines...) Expand all
255 return current_frame_bounds; 264 return current_frame_bounds;
256 } 265 }
257 266
258 void AutocompletePopupContentsView::LayoutChildren() { 267 void AutocompletePopupContentsView::LayoutChildren() {
259 gfx::Rect contents_rect = GetContentsBounds(); 268 gfx::Rect contents_rect = GetContentsBounds();
260 int top = contents_rect.y(); 269 int top = contents_rect.y();
261 for (int i = 0; i < child_count(); ++i) { 270 for (int i = 0; i < child_count(); ++i) {
262 View* v = child_at(i); 271 View* v = child_at(i);
263 if (v->IsVisible()) { 272 if (v->IsVisible()) {
264 v->SetBounds(contents_rect.x(), top, contents_rect.width(), 273 v->SetBounds(contents_rect.x(), top, contents_rect.width(),
265 v->GetPreferredSize().height()); 274 v->GetPreferredSize().height());
Peter Kasting 2011/12/15 22:56:04 Nit: This indentation was fine.
266 top = v->bounds().bottom(); 275 top = v->bounds().bottom();
267 } 276 }
268 } 277 }
269 } 278 }
270 279
271 //////////////////////////////////////////////////////////////////////////////// 280 ////////////////////////////////////////////////////////////////////////////////
272 // AutocompletePopupContentsView, AutocompletePopupView overrides: 281 // AutocompletePopupContentsView, AutocompletePopupView overrides:
273 282
274 bool AutocompletePopupContentsView::IsOpen() const { 283 bool AutocompletePopupContentsView::IsOpen() const {
275 return (popup_ != NULL); 284 return (popup_ != NULL);
276 } 285 }
277 286
278 void AutocompletePopupContentsView::InvalidateLine(size_t line) { 287 void AutocompletePopupContentsView::InvalidateLine(size_t line) {
279 child_at(static_cast<int>(line))->SchedulePaint(); 288 AutocompleteResultView* result = static_cast<AutocompleteResultView*>(
289 child_at(static_cast<int>(line)));
290 result->SchedulePaint();
291
292 if (HasMatchAt(line) && GetMatchAtIndex(line).associated_keyword.get())
293 result->ShowKeyword(
294 model_->selected_line_state() == AutocompletePopupModel::KEYWORD);
280 } 295 }
281 296
282 void AutocompletePopupContentsView::UpdatePopupAppearance() { 297 void AutocompletePopupContentsView::UpdatePopupAppearance() {
283 if (model_->result().empty()) { 298 if (model_->result().empty()) {
284 // No matches, close any existing popup. 299 // No matches, close any existing popup.
285 if (popup_ != NULL) { 300 if (popup_ != NULL) {
286 size_animation_.Stop(); 301 size_animation_.Stop();
302
287 // NOTE: Do NOT use CloseNow() here, as we may be deep in a callstack 303 // NOTE: Do NOT use CloseNow() here, as we may be deep in a callstack
288 // triggered by the popup receiving a message (e.g. LBUTTONUP), and 304 // triggered by the popup receiving a message (e.g. LBUTTONUP), and
289 // destroying the popup would cause us to read garbage when we unwind back 305 // destroying the popup would cause us to read garbage when we unwind back
290 // to that level. 306 // to that level.
291 popup_->Close(); // This will eventually delete the popup. 307 popup_->Close(); // This will eventually delete the popup.
292 popup_.reset(); 308 popup_.reset();
293 } 309 }
294 return; 310 return;
295 } 311 }
296 312
297 // Update the match cached by each row, in the process of doing so make sure 313 // Update the match cached by each row, in the process of doing so make sure
298 // we have enough row views. 314 // we have enough row views.
299 size_t child_rv_count = child_count(); 315 size_t child_rv_count = child_count();
300 if (opt_in_view_) { 316 if (opt_in_view_) {
301 DCHECK_GT(child_rv_count, 0u); 317 DCHECK_GT(child_rv_count, 0u);
302 child_rv_count--; 318 child_rv_count--;
303 } 319 }
304 for (size_t i = 0; i < model_->result().size(); ++i) { 320 const size_t result_size = model_->result().size();
305 AutocompleteResultView* result_view; 321 for (size_t i = 0; i < result_size; ++i) {
306 if (i >= child_rv_count) { 322 const AutocompleteMatch& match = GetMatchAtIndex(i);
307 result_view = 323 AutocompleteResultView* view = static_cast<AutocompleteResultView*>(
308 CreateResultView(this, i, result_font_, result_bold_font_); 324 child_at(i));
309 AddChildViewAt(result_view, static_cast<int>(i)); 325 view->SetMatch(match);
310 } else { 326 view->SetVisible(true);
311 result_view = static_cast<AutocompleteResultView*>(child_at(i));
312 result_view->SetVisible(true);
313 }
314 result_view->SetMatch(GetMatchAtIndex(i));
315 } 327 }
316 for (size_t i = model_->result().size(); i < child_rv_count; ++i) 328 for (size_t i = result_size; i < child_rv_count; ++i)
317 child_at(i)->SetVisible(false); 329 child_at(i)->SetVisible(false);
318 330
319 PromoCounter* counter = profile_->GetInstantPromoCounter(); 331 PromoCounter* counter = profile_->GetInstantPromoCounter();
320 if (!opt_in_view_ && counter && counter->ShouldShow(base::Time::Now())) { 332 if (!opt_in_view_ && counter && counter->ShouldShow(base::Time::Now())) {
321 opt_in_view_ = new InstantOptInView(this, result_bold_font_, result_font_); 333 opt_in_view_ = new InstantOptInView(this, result_bold_font_, result_font_);
322 AddChildView(opt_in_view_); 334 AddChildView(opt_in_view_);
323 } else if (opt_in_view_ && (!counter || 335 } else if (opt_in_view_ && (!counter ||
324 !counter->ShouldShow(base::Time::Now()))) { 336 !counter->ShouldShow(base::Time::Now()))) {
325 delete opt_in_view_; 337 delete opt_in_view_;
326 opt_in_view_ = NULL; 338 opt_in_view_ = NULL;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 } 390 }
379 391
380 void AutocompletePopupContentsView::OnDragCanceled() { 392 void AutocompletePopupContentsView::OnDragCanceled() {
381 ignore_mouse_drag_ = true; 393 ignore_mouse_drag_ = true;
382 } 394 }
383 395
384 //////////////////////////////////////////////////////////////////////////////// 396 ////////////////////////////////////////////////////////////////////////////////
385 // AutocompletePopupContentsView, AutocompleteResultViewModel implementation: 397 // AutocompletePopupContentsView, AutocompleteResultViewModel implementation:
386 398
387 bool AutocompletePopupContentsView::IsSelectedIndex(size_t index) const { 399 bool AutocompletePopupContentsView::IsSelectedIndex(size_t index) const {
388 return HasMatchAt(index) ? index == model_->selected_line() : false; 400 return index == model_->selected_line();
389 } 401 }
390 402
391 bool AutocompletePopupContentsView::IsHoveredIndex(size_t index) const { 403 bool AutocompletePopupContentsView::IsHoveredIndex(size_t index) const {
392 return HasMatchAt(index) ? index == model_->hovered_line() : false; 404 return index == model_->hovered_line();
393 } 405 }
394 406
395 const SkBitmap* AutocompletePopupContentsView::GetIconIfExtensionMatch( 407 const SkBitmap* AutocompletePopupContentsView::GetIconIfExtensionMatch(
396 size_t index) const { 408 size_t index) const {
397 if (!HasMatchAt(index)) 409 if (!HasMatchAt(index))
398 return NULL; 410 return NULL;
399 return model_->GetIconIfExtensionMatch(GetMatchAtIndex(index)); 411 return model_->GetIconIfExtensionMatch(GetMatchAtIndex(index));
400 } 412 }
401 413
402 //////////////////////////////////////////////////////////////////////////////// 414 ////////////////////////////////////////////////////////////////////////////////
(...skipping 15 matching lines...) Expand all
418 // Size our children to the available content area. 430 // Size our children to the available content area.
419 LayoutChildren(); 431 LayoutChildren();
420 432
421 // 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
422 // won't implicitly require painting until we ask for one. 434 // won't implicitly require painting until we ask for one.
423 SchedulePaint(); 435 SchedulePaint();
424 } 436 }
425 437
426 views::View* AutocompletePopupContentsView::GetEventHandlerForPoint( 438 views::View* AutocompletePopupContentsView::GetEventHandlerForPoint(
427 const gfx::Point& point) { 439 const gfx::Point& point) {
428 // If there is no opt in view, then we want all mouse events. Otherwise let 440 views::View* child = views::View::GetEventHandlerForPoint(point);
429 // any descendants of the opt-in view get mouse events. 441
430 if (!opt_in_view_) 442 // If there is no opt in view, and the mouse isn't over a keyword button,
443 // then we want all mouse events. Otherwise let any descendants of the
444 // opt-in view get mouse events.
445 if (child->id() == AutocompleteResultView::VIEW_ID_KEYWORD)
446 return child;
447 else if (!opt_in_view_)
Peter Kasting 2011/12/15 22:56:04 Nit: No else after return
431 return this; 448 return this;
432 449
433 views::View* child = views::View::GetEventHandlerForPoint(point);
434 views::View* ancestor = child; 450 views::View* ancestor = child;
435 while (ancestor && ancestor != opt_in_view_) 451 while (ancestor && ancestor != opt_in_view_)
436 ancestor = ancestor->parent(); 452 ancestor = ancestor->parent();
437 return ancestor ? child : this; 453 return ancestor ? child : this;
438 } 454 }
439 455
440 bool AutocompletePopupContentsView::OnMousePressed( 456 bool AutocompletePopupContentsView::OnMousePressed(
441 const views::MouseEvent& event) { 457 const views::MouseEvent& event) {
442 ignore_mouse_drag_ = false; // See comment on |ignore_mouse_drag_| in header. 458 ignore_mouse_drag_ = false; // See comment on |ignore_mouse_drag_| in header.
443 if (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) { 459 if (event.IsLeftMouseButton() || event.IsMiddleMouseButton()) {
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 void AutocompletePopupContentsView::OpenIndex( 645 void AutocompletePopupContentsView::OpenIndex(
630 size_t index, 646 size_t index,
631 WindowOpenDisposition disposition) { 647 WindowOpenDisposition disposition) {
632 if (!HasMatchAt(index)) 648 if (!HasMatchAt(index))
633 return; 649 return;
634 650
635 // OpenMatch() may close the popup, which will clear the result set and, by 651 // OpenMatch() may close the popup, which will clear the result set and, by
636 // extension, |match| and its contents. So copy the relevant match out to 652 // extension, |match| and its contents. So copy the relevant match out to
637 // make sure it stays alive until the call completes. 653 // make sure it stays alive until the call completes.
638 AutocompleteMatch match = model_->result().match_at(index); 654 AutocompleteMatch match = model_->result().match_at(index);
639 string16 keyword;
640 const bool is_keyword_hint = model_->GetKeywordForMatch(match, &keyword);
641 omnibox_view_->OpenMatch(match, disposition, GURL(), index, 655 omnibox_view_->OpenMatch(match, disposition, GURL(), index,
642 is_keyword_hint ? string16() : keyword); 656 match.keyword);
643 } 657 }
644 658
645 size_t AutocompletePopupContentsView::GetIndexForPoint( 659 size_t AutocompletePopupContentsView::GetIndexForPoint(
646 const gfx::Point& point) { 660 const gfx::Point& point) {
647 if (!HitTest(point)) 661 if (!HitTest(point))
648 return AutocompletePopupModel::kNoMatch; 662 return AutocompletePopupModel::kNoMatch;
649 663
650 int nb_match = model_->result().size(); 664 int nb_match = model_->result().size();
651 DCHECK(nb_match <= child_count()); 665 DCHECK(nb_match <= child_count());
652 for (int i = 0; i < nb_match; ++i) { 666 for (int i = 0; i < nb_match; ++i) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 opt_in_view_ = NULL; 701 opt_in_view_ = NULL;
688 PromoCounter* counter = profile_->GetInstantPromoCounter(); 702 PromoCounter* counter = profile_->GetInstantPromoCounter();
689 DCHECK(counter); 703 DCHECK(counter);
690 counter->Hide(); 704 counter->Hide();
691 if (opt_in) { 705 if (opt_in) {
692 browser::ShowInstantConfirmDialogIfNecessary( 706 browser::ShowInstantConfirmDialogIfNecessary(
693 location_bar_->GetWidget()->GetNativeWindow(), profile_); 707 location_bar_->GetWidget()->GetNativeWindow(), profile_);
694 } 708 }
695 UpdatePopupAppearance(); 709 UpdatePopupAppearance();
696 } 710 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698