| 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 #include "ui/views/controls/scroll_view.h" | 5 #include "ui/views/controls/scroll_view.h" |
| 6 | 6 |
| 7 #include "base/feature_list.h" | 7 #include "base/feature_list.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/macros.h" | 9 #include "base/macros.h" |
| 10 #include "ui/base/material_design/material_design_controller.h" | 10 #include "ui/base/material_design/material_design_controller.h" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 int CheckScrollBounds(int viewport_size, int content_size, int current_pos) { | 54 int CheckScrollBounds(int viewport_size, int content_size, int current_pos) { |
| 55 int max = std::max(content_size - viewport_size, 0); | 55 int max = std::max(content_size - viewport_size, 0); |
| 56 if (current_pos < 0) | 56 if (current_pos < 0) |
| 57 return 0; | 57 return 0; |
| 58 if (current_pos > max) | 58 if (current_pos > max) |
| 59 return max; | 59 return max; |
| 60 return current_pos; | 60 return current_pos; |
| 61 } | 61 } |
| 62 | 62 |
| 63 // Make sure the content is not scrolled out of bounds | 63 // Make sure the content is not scrolled out of bounds |
| 64 void ConstrainScrollToBounds(View* viewport, View* view) { | 64 void ConstrainScrollToBounds(View* viewport, |
| 65 View* view, |
| 66 bool scroll_with_layers_enabled) { |
| 65 if (!view) | 67 if (!view) |
| 66 return; | 68 return; |
| 67 | 69 |
| 68 // Note that even when ScrollView::ScrollsWithLayers() is true, the header row | 70 // Note that even when ScrollView::ScrollsWithLayers() is true, the header row |
| 69 // scrolls by repainting. | 71 // scrolls by repainting. |
| 70 const bool scrolls_with_layers = viewport->layer() != nullptr; | 72 const bool scrolls_with_layers = |
| 73 scroll_with_layers_enabled && viewport->layer() != nullptr; |
| 71 if (scrolls_with_layers) { | 74 if (scrolls_with_layers) { |
| 72 DCHECK(view->layer()); | 75 DCHECK(view->layer()); |
| 73 DCHECK_EQ(0, view->x()); | 76 DCHECK_EQ(0, view->x()); |
| 74 DCHECK_EQ(0, view->y()); | 77 DCHECK_EQ(0, view->y()); |
| 75 } | 78 } |
| 76 gfx::ScrollOffset offset = scrolls_with_layers | 79 gfx::ScrollOffset offset = scrolls_with_layers |
| 77 ? view->layer()->CurrentScrollOffset() | 80 ? view->layer()->CurrentScrollOffset() |
| 78 : gfx::ScrollOffset(-view->x(), -view->y()); | 81 : gfx::ScrollOffset(-view->x(), -view->y()); |
| 79 | 82 |
| 80 int x = CheckScrollBounds(viewport->width(), view->width(), offset.x()); | 83 int x = CheckScrollBounds(viewport->width(), view->width(), offset.x()); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 AddChildView(header_viewport_); | 162 AddChildView(header_viewport_); |
| 160 | 163 |
| 161 // Don't add the scrollbars as children until we discover we need them | 164 // Don't add the scrollbars as children until we discover we need them |
| 162 // (ShowOrHideScrollBar). | 165 // (ShowOrHideScrollBar). |
| 163 horiz_sb_->SetVisible(false); | 166 horiz_sb_->SetVisible(false); |
| 164 horiz_sb_->set_controller(this); | 167 horiz_sb_->set_controller(this); |
| 165 vert_sb_->SetVisible(false); | 168 vert_sb_->SetVisible(false); |
| 166 vert_sb_->set_controller(this); | 169 vert_sb_->set_controller(this); |
| 167 corner_view_->SetVisible(false); | 170 corner_view_->SetVisible(false); |
| 168 | 171 |
| 169 if (!base::FeatureList::IsEnabled(kToolkitViewsScrollWithLayers)) | 172 scroll_with_layers_enabled_ = |
| 173 base::FeatureList::IsEnabled(kToolkitViewsScrollWithLayers); |
| 174 if (!scroll_with_layers_enabled_) |
| 170 return; | 175 return; |
| 176 |
| 171 EnableViewPortLayer(); | 177 EnableViewPortLayer(); |
| 172 } | 178 } |
| 173 | 179 |
| 174 ScrollView::~ScrollView() { | 180 ScrollView::~ScrollView() { |
| 175 // The scrollbars may not have been added, delete them to ensure they get | 181 // The scrollbars may not have been added, delete them to ensure they get |
| 176 // deleted. | 182 // deleted. |
| 177 delete horiz_sb_; | 183 delete horiz_sb_; |
| 178 delete vert_sb_; | 184 delete vert_sb_; |
| 179 delete corner_view_; | 185 delete corner_view_; |
| 180 } | 186 } |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 gfx::Size container_size = contents_ ? contents_->size() : gfx::Size(); | 449 gfx::Size container_size = contents_ ? contents_->size() : gfx::Size(); |
| 444 container_size.SetToMax(viewport_bounds.size()); | 450 container_size.SetToMax(viewport_bounds.size()); |
| 445 contents_->SetBoundsRect(gfx::Rect(container_size)); | 451 contents_->SetBoundsRect(gfx::Rect(container_size)); |
| 446 } | 452 } |
| 447 | 453 |
| 448 header_viewport_->SetBounds(contents_x, contents_y, | 454 header_viewport_->SetBounds(contents_x, contents_y, |
| 449 viewport_bounds.width(), header_height); | 455 viewport_bounds.width(), header_height); |
| 450 if (header_) | 456 if (header_) |
| 451 header_->Layout(); | 457 header_->Layout(); |
| 452 | 458 |
| 453 ConstrainScrollToBounds(header_viewport_, header_); | 459 ConstrainScrollToBounds(header_viewport_, header_, |
| 454 ConstrainScrollToBounds(contents_viewport_, contents_); | 460 scroll_with_layers_enabled_); |
| 461 ConstrainScrollToBounds(contents_viewport_, contents_, |
| 462 scroll_with_layers_enabled_); |
| 455 SchedulePaint(); | 463 SchedulePaint(); |
| 456 UpdateScrollBarPositions(); | 464 UpdateScrollBarPositions(); |
| 457 } | 465 } |
| 458 | 466 |
| 459 bool ScrollView::OnKeyPressed(const ui::KeyEvent& event) { | 467 bool ScrollView::OnKeyPressed(const ui::KeyEvent& event) { |
| 460 bool processed = false; | 468 bool processed = false; |
| 461 | 469 |
| 462 // Give vertical scrollbar priority | 470 // Give vertical scrollbar priority |
| 463 if (vert_sb_->visible()) | 471 if (vert_sb_->visible()) |
| 464 processed = vert_sb_->OnKeyPressed(event); | 472 processed = vert_sb_->OnKeyPressed(event); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 } | 528 } |
| 521 | 529 |
| 522 const char* ScrollView::GetClassName() const { | 530 const char* ScrollView::GetClassName() const { |
| 523 return kViewClassName; | 531 return kViewClassName; |
| 524 } | 532 } |
| 525 | 533 |
| 526 void ScrollView::OnNativeThemeChanged(const ui::NativeTheme* theme) { | 534 void ScrollView::OnNativeThemeChanged(const ui::NativeTheme* theme) { |
| 527 UpdateBorder(); | 535 UpdateBorder(); |
| 528 } | 536 } |
| 529 | 537 |
| 538 void ScrollView::ViewHierarchyChanged( |
| 539 const ViewHierarchyChangedDetails& details) { |
| 540 if (details.is_add && Contains(details.parent) && !viewport_layer_enabled_) |
| 541 EnableLayeringRecursivelyForChild(details.child); |
| 542 } |
| 543 |
| 544 void ScrollView::OnChildLayerChanged(View* child) { |
| 545 EnableViewPortLayer(); |
| 546 } |
| 547 |
| 530 void ScrollView::ScrollToPosition(ScrollBar* source, int position) { | 548 void ScrollView::ScrollToPosition(ScrollBar* source, int position) { |
| 531 if (!contents_) | 549 if (!contents_) |
| 532 return; | 550 return; |
| 533 | 551 |
| 534 gfx::ScrollOffset offset = CurrentOffset(); | 552 gfx::ScrollOffset offset = CurrentOffset(); |
| 535 if (source == horiz_sb_ && horiz_sb_->visible()) { | 553 if (source == horiz_sb_ && horiz_sb_->visible()) { |
| 536 position = AdjustPosition(offset.x(), position, contents_->width(), | 554 position = AdjustPosition(offset.x(), position, contents_->width(), |
| 537 contents_viewport_->width()); | 555 contents_viewport_->width()); |
| 538 if (offset.x() == position) | 556 if (offset.x() == position) |
| 539 return; | 557 return; |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 // and commits a frame, which isn't true in some tests. | 728 // and commits a frame, which isn't true in some tests. |
| 711 // See http://crbug.com/637521. | 729 // See http://crbug.com/637521. |
| 712 OnLayerScrolled(offset); | 730 OnLayerScrolled(offset); |
| 713 } else { | 731 } else { |
| 714 contents_->SetPosition(gfx::Point(-offset.x(), -offset.y())); | 732 contents_->SetPosition(gfx::Point(-offset.x(), -offset.y())); |
| 715 ScrollHeader(); | 733 ScrollHeader(); |
| 716 } | 734 } |
| 717 } | 735 } |
| 718 | 736 |
| 719 bool ScrollView::ScrollsWithLayers() const { | 737 bool ScrollView::ScrollsWithLayers() const { |
| 738 if (!scroll_with_layers_enabled_) |
| 739 return false; |
| 720 // Just check for the presence of a layer since it's cheaper than querying the | 740 // Just check for the presence of a layer since it's cheaper than querying the |
| 721 // Feature flag each time. | 741 // Feature flag each time. |
| 722 return contents_viewport_->layer() != nullptr; | 742 return contents_viewport_->layer() != nullptr; |
| 723 } | 743 } |
| 724 | 744 |
| 725 void ScrollView::EnableViewPortLayer() { | 745 void ScrollView::EnableViewPortLayer() { |
| 746 if (viewport_layer_enabled_) |
| 747 return; |
| 748 |
| 749 viewport_layer_enabled_ = true; |
| 726 background_color_ = SK_ColorWHITE; | 750 background_color_ = SK_ColorWHITE; |
| 727 contents_viewport_->set_background( | 751 contents_viewport_->set_background( |
| 728 Background::CreateSolidBackground(background_color_)); | 752 Background::CreateSolidBackground(background_color_)); |
| 729 contents_viewport_->SetPaintToLayer(); | 753 contents_viewport_->SetPaintToLayer(); |
| 730 contents_viewport_->layer()->SetMasksToBounds(true); | 754 contents_viewport_->layer()->SetMasksToBounds(true); |
| 731 } | 755 } |
| 732 | 756 |
| 733 void ScrollView::OnLayerScrolled(const gfx::ScrollOffset&) { | 757 void ScrollView::OnLayerScrolled(const gfx::ScrollOffset&) { |
| 734 UpdateScrollBarPositions(); | 758 UpdateScrollBarPositions(); |
| 735 ScrollHeader(); | 759 ScrollHeader(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 756 return; | 780 return; |
| 757 | 781 |
| 758 SetBorder(CreateSolidBorder( | 782 SetBorder(CreateSolidBorder( |
| 759 1, | 783 1, |
| 760 GetNativeTheme()->GetSystemColor( | 784 GetNativeTheme()->GetSystemColor( |
| 761 draw_focus_indicator_ | 785 draw_focus_indicator_ |
| 762 ? ui::NativeTheme::kColorId_FocusedBorderColor | 786 ? ui::NativeTheme::kColorId_FocusedBorderColor |
| 763 : ui::NativeTheme::kColorId_UnfocusedBorderColor))); | 787 : ui::NativeTheme::kColorId_UnfocusedBorderColor))); |
| 764 } | 788 } |
| 765 | 789 |
| 790 bool ScrollView::EnableLayeringRecursivelyForChild(View* view) { |
| 791 if (viewport_layer_enabled_ || scroll_with_layers_enabled_) |
| 792 return true; |
| 793 |
| 794 if (view->layer()) { |
| 795 EnableViewPortLayer(); |
| 796 return true; |
| 797 } |
| 798 |
| 799 for (int i = 0; i < view->child_count(); ++i) { |
| 800 if (EnableLayeringRecursivelyForChild(view->child_at(i))) |
| 801 return true; |
| 802 } |
| 803 return false; |
| 804 } |
| 805 |
| 766 // VariableRowHeightScrollHelper ---------------------------------------------- | 806 // VariableRowHeightScrollHelper ---------------------------------------------- |
| 767 | 807 |
| 768 VariableRowHeightScrollHelper::VariableRowHeightScrollHelper( | 808 VariableRowHeightScrollHelper::VariableRowHeightScrollHelper( |
| 769 Controller* controller) : controller_(controller) { | 809 Controller* controller) : controller_(controller) { |
| 770 } | 810 } |
| 771 | 811 |
| 772 VariableRowHeightScrollHelper::~VariableRowHeightScrollHelper() { | 812 VariableRowHeightScrollHelper::~VariableRowHeightScrollHelper() { |
| 773 } | 813 } |
| 774 | 814 |
| 775 int VariableRowHeightScrollHelper::GetPageScrollIncrement( | 815 int VariableRowHeightScrollHelper::GetPageScrollIncrement( |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 | 870 |
| 831 VariableRowHeightScrollHelper::RowInfo | 871 VariableRowHeightScrollHelper::RowInfo |
| 832 FixedRowHeightScrollHelper::GetRowInfo(int y) { | 872 FixedRowHeightScrollHelper::GetRowInfo(int y) { |
| 833 if (y < top_margin_) | 873 if (y < top_margin_) |
| 834 return RowInfo(0, top_margin_); | 874 return RowInfo(0, top_margin_); |
| 835 return RowInfo((y - top_margin_) / row_height_ * row_height_ + top_margin_, | 875 return RowInfo((y - top_margin_) / row_height_ * row_height_ + top_margin_, |
| 836 row_height_); | 876 row_height_); |
| 837 } | 877 } |
| 838 | 878 |
| 839 } // namespace views | 879 } // namespace views |
| OLD | NEW |