| 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 "app/gfx/canvas.h" | 7 #include "app/gfx/canvas.h" |
| 8 #include "app/gfx/color_utils.h" | 8 #include "app/gfx/color_utils.h" |
| 9 #include "app/gfx/insets.h" | 9 #include "app/gfx/insets.h" |
| 10 #include "app/gfx/path.h" | 10 #include "app/gfx/path.h" |
| (...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 | 589 |
| 590 //////////////////////////////////////////////////////////////////////////////// | 590 //////////////////////////////////////////////////////////////////////////////// |
| 591 // AutocompletePopupContentsView, public: | 591 // AutocompletePopupContentsView, public: |
| 592 | 592 |
| 593 AutocompletePopupContentsView::AutocompletePopupContentsView( | 593 AutocompletePopupContentsView::AutocompletePopupContentsView( |
| 594 const gfx::Font& font, | 594 const gfx::Font& font, |
| 595 AutocompleteEditView* edit_view, | 595 AutocompleteEditView* edit_view, |
| 596 AutocompleteEditModel* edit_model, | 596 AutocompleteEditModel* edit_model, |
| 597 Profile* profile, | 597 Profile* profile, |
| 598 const BubblePositioner* bubble_positioner) | 598 const BubblePositioner* bubble_positioner) |
| 599 #if defined(OS_WIN) | 599 : model_(new AutocompletePopupModel(this, edit_model, profile)), |
| 600 : popup_(new AutocompletePopupWin(this)), | |
| 601 #else | |
| 602 : popup_(new AutocompletePopupGtk(this)), | |
| 603 #endif | |
| 604 model_(new AutocompletePopupModel(this, edit_model, profile)), | |
| 605 edit_view_(edit_view), | 600 edit_view_(edit_view), |
| 606 bubble_positioner_(bubble_positioner), | 601 bubble_positioner_(bubble_positioner), |
| 607 result_font_(font.DeriveFont(kEditFontAdjust)), | 602 result_font_(font.DeriveFont(kEditFontAdjust)), |
| 608 ALLOW_THIS_IN_INITIALIZER_LIST(size_animation_(this)), | 603 ALLOW_THIS_IN_INITIALIZER_LIST(size_animation_(this)) { |
| 609 is_open_(false) { | |
| 610 // The following little dance is required because set_border() requires a | 604 // The following little dance is required because set_border() requires a |
| 611 // pointer to a non-const object. | 605 // pointer to a non-const object. |
| 612 BubbleBorder* bubble_border = new BubbleBorder; | 606 BubbleBorder* bubble_border = new BubbleBorder; |
| 613 bubble_border_ = bubble_border; | 607 bubble_border_ = bubble_border; |
| 614 set_border(bubble_border); | 608 set_border(bubble_border); |
| 615 } | 609 } |
| 616 | 610 |
| 617 gfx::Rect AutocompletePopupContentsView::GetPopupBounds() const { | 611 gfx::Rect AutocompletePopupContentsView::GetPopupBounds() const { |
| 618 if (!size_animation_.IsAnimating()) | 612 if (!size_animation_.IsAnimating()) |
| 619 return target_bounds_; | 613 return target_bounds_; |
| 620 | 614 |
| 621 gfx::Rect current_frame_bounds = start_bounds_; | 615 gfx::Rect current_frame_bounds = start_bounds_; |
| 622 int total_height_delta = target_bounds_.height() - start_bounds_.height(); | 616 int total_height_delta = target_bounds_.height() - start_bounds_.height(); |
| 623 // Round |current_height_delta| instead of truncating so we won't leave single | 617 // Round |current_height_delta| instead of truncating so we won't leave single |
| 624 // white pixels at the bottom of the popup as long when animating very small | 618 // white pixels at the bottom of the popup as long when animating very small |
| 625 // height differences. | 619 // height differences. |
| 626 int current_height_delta = static_cast<int>( | 620 int current_height_delta = static_cast<int>( |
| 627 size_animation_.GetCurrentValue() * total_height_delta - 0.5); | 621 size_animation_.GetCurrentValue() * total_height_delta - 0.5); |
| 628 current_frame_bounds.set_height( | 622 current_frame_bounds.set_height( |
| 629 current_frame_bounds.height() + current_height_delta); | 623 current_frame_bounds.height() + current_height_delta); |
| 630 return current_frame_bounds; | 624 return current_frame_bounds; |
| 631 } | 625 } |
| 632 | 626 |
| 633 //////////////////////////////////////////////////////////////////////////////// | 627 //////////////////////////////////////////////////////////////////////////////// |
| 634 // AutocompletePopupContentsView, AutocompletePopupView overrides: | 628 // AutocompletePopupContentsView, AutocompletePopupView overrides: |
| 635 | 629 |
| 636 bool AutocompletePopupContentsView::IsOpen() const { | 630 bool AutocompletePopupContentsView::IsOpen() const { |
| 637 const bool is_open = popup_->IsOpen(); | 631 return (popup_ != NULL); |
| 638 CHECK(is_open == is_open_); | |
| 639 return is_open; | |
| 640 } | 632 } |
| 641 | 633 |
| 642 void AutocompletePopupContentsView::InvalidateLine(size_t line) { | 634 void AutocompletePopupContentsView::InvalidateLine(size_t line) { |
| 643 GetChildViewAt(static_cast<int>(line))->SchedulePaint(); | 635 GetChildViewAt(static_cast<int>(line))->SchedulePaint(); |
| 644 } | 636 } |
| 645 | 637 |
| 646 void AutocompletePopupContentsView::UpdatePopupAppearance() { | 638 void AutocompletePopupContentsView::UpdatePopupAppearance() { |
| 647 if (model_->result().empty()) { | 639 if (model_->result().empty()) { |
| 648 // No matches, close any existing popup. | 640 // No matches, close any existing popup. |
| 649 if (popup_->IsCreated()) { | 641 if (popup_ != NULL) { |
| 650 size_animation_.Stop(); | 642 size_animation_.Stop(); |
| 651 popup_->Hide(); | 643 popup_.reset(); |
| 652 } | 644 } |
| 653 is_open_ = false; | |
| 654 return; | 645 return; |
| 655 } | 646 } |
| 656 | 647 |
| 657 // Update the match cached by each row, in the process of doing so make sure | 648 // Update the match cached by each row, in the process of doing so make sure |
| 658 // we have enough row views. | 649 // we have enough row views. |
| 659 int total_child_height = 0; | 650 int total_child_height = 0; |
| 660 size_t child_view_count = GetChildViewCount(); | 651 size_t child_view_count = GetChildViewCount(); |
| 661 for (size_t i = 0; i < model_->result().size(); ++i) { | 652 for (size_t i = 0; i < model_->result().size(); ++i) { |
| 662 AutocompleteResultView* result_view; | 653 AutocompleteResultView* result_view; |
| 663 if (i >= child_view_count) { | 654 if (i >= child_view_count) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 677 gfx::Size(location_stack_bounds.width(), total_child_height))); | 668 gfx::Size(location_stack_bounds.width(), total_child_height))); |
| 678 | 669 |
| 679 // If we're animating and our target height changes, reset the animation. | 670 // If we're animating and our target height changes, reset the animation. |
| 680 // NOTE: If we just reset blindly on _every_ update, then when the user types | 671 // NOTE: If we just reset blindly on _every_ update, then when the user types |
| 681 // rapidly we could get "stuck" trying repeatedly to animate shrinking by the | 672 // rapidly we could get "stuck" trying repeatedly to animate shrinking by the |
| 682 // last few pixels to get to one visible result. | 673 // last few pixels to get to one visible result. |
| 683 if (new_target_bounds.height() != target_bounds_.height()) | 674 if (new_target_bounds.height() != target_bounds_.height()) |
| 684 size_animation_.Reset(); | 675 size_animation_.Reset(); |
| 685 target_bounds_ = new_target_bounds; | 676 target_bounds_ = new_target_bounds; |
| 686 | 677 |
| 687 if (!popup_->IsCreated()) { | 678 if (popup_ == NULL) { |
| 688 // If we've never been shown, we need to create the window. | 679 // If the popup is currently closed, we need to create it. |
| 689 popup_->Init(edit_view_, this); | 680 popup_.reset(new AutocompletePopupClass(edit_view_, this)); |
| 690 } else { | 681 } else { |
| 691 // Animate the popup shrinking, but don't animate growing larger (or | 682 // Animate the popup shrinking, but don't animate growing larger since that |
| 692 // appearing for the first time) since that would make the popup feel less | 683 // would make the popup feel less responsive. |
| 693 // responsive. | |
| 694 GetWidget()->GetBounds(&start_bounds_, true); | 684 GetWidget()->GetBounds(&start_bounds_, true); |
| 695 if (popup_->IsVisible() && | 685 if (target_bounds_.height() < start_bounds_.height()) |
| 696 (target_bounds_.height() < start_bounds_.height())) | |
| 697 size_animation_.Show(); | 686 size_animation_.Show(); |
| 698 else | 687 else |
| 699 start_bounds_ = target_bounds_; | 688 start_bounds_ = target_bounds_; |
| 700 popup_->Show(); | 689 popup_->SetBounds(GetPopupBounds()); |
| 701 } | 690 } |
| 702 is_open_ = true; | |
| 703 | 691 |
| 704 SchedulePaint(); | 692 SchedulePaint(); |
| 705 } | 693 } |
| 706 | 694 |
| 707 void AutocompletePopupContentsView::PaintUpdatesNow() { | 695 void AutocompletePopupContentsView::PaintUpdatesNow() { |
| 708 // TODO(beng): remove this from the interface. | 696 // TODO(beng): remove this from the interface. |
| 709 } | 697 } |
| 710 | 698 |
| 711 AutocompletePopupModel* AutocompletePopupContentsView::GetModel() { | 699 AutocompletePopupModel* AutocompletePopupContentsView::GetModel() { |
| 712 return model_.get(); | 700 return model_.get(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 if (HasMatchAt(index)) | 738 if (HasMatchAt(index)) |
| 751 model_->SetSelectedLine(index, revert_to_default); | 739 model_->SetSelectedLine(index, revert_to_default); |
| 752 } | 740 } |
| 753 | 741 |
| 754 //////////////////////////////////////////////////////////////////////////////// | 742 //////////////////////////////////////////////////////////////////////////////// |
| 755 // AutocompletePopupContentsView, AnimationDelegate implementation: | 743 // AutocompletePopupContentsView, AnimationDelegate implementation: |
| 756 | 744 |
| 757 void AutocompletePopupContentsView::AnimationProgressed( | 745 void AutocompletePopupContentsView::AnimationProgressed( |
| 758 const Animation* animation) { | 746 const Animation* animation) { |
| 759 // We should only be running the animation when the popup is already visible. | 747 // We should only be running the animation when the popup is already visible. |
| 760 CHECK(IsOpen()); | 748 DCHECK(popup_ != NULL); |
| 761 popup_->Show(); // Adjusts bounds. | 749 popup_->SetBounds(GetPopupBounds()); |
| 762 } | 750 } |
| 763 | 751 |
| 764 //////////////////////////////////////////////////////////////////////////////// | 752 //////////////////////////////////////////////////////////////////////////////// |
| 765 // AutocompletePopupContentsView, views::View overrides: | 753 // AutocompletePopupContentsView, views::View overrides: |
| 766 | 754 |
| 767 void AutocompletePopupContentsView::Paint(gfx::Canvas* canvas) { | 755 void AutocompletePopupContentsView::Paint(gfx::Canvas* canvas) { |
| 768 // We paint our children in an unconventional way. | 756 // We paint our children in an unconventional way. |
| 769 // | 757 // |
| 770 // Because the border of this view creates an anti-aliased round-rect region | 758 // Because the border of this view creates an anti-aliased round-rect region |
| 771 // for the contents, we need to render our rectangular result child views into | 759 // for the contents, we need to render our rectangular result child views into |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 // static | 877 // static |
| 890 AutocompletePopupView* AutocompletePopupView::CreatePopupView( | 878 AutocompletePopupView* AutocompletePopupView::CreatePopupView( |
| 891 const gfx::Font& font, | 879 const gfx::Font& font, |
| 892 AutocompleteEditView* edit_view, | 880 AutocompleteEditView* edit_view, |
| 893 AutocompleteEditModel* edit_model, | 881 AutocompleteEditModel* edit_model, |
| 894 Profile* profile, | 882 Profile* profile, |
| 895 const BubblePositioner* bubble_positioner) { | 883 const BubblePositioner* bubble_positioner) { |
| 896 return new AutocompletePopupContentsView(font, edit_view, edit_model, | 884 return new AutocompletePopupContentsView(font, edit_view, edit_model, |
| 897 profile, bubble_positioner); | 885 profile, bubble_positioner); |
| 898 } | 886 } |
| OLD | NEW |