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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 : contents_(NULL), | 148 : contents_(NULL), |
146 contents_viewport_(new Viewport()), | 149 contents_viewport_(new Viewport()), |
147 header_(NULL), | 150 header_(NULL), |
148 header_viewport_(new Viewport()), | 151 header_viewport_(new Viewport()), |
149 horiz_sb_(PlatformStyle::CreateScrollBar(true).release()), | 152 horiz_sb_(PlatformStyle::CreateScrollBar(true).release()), |
150 vert_sb_(PlatformStyle::CreateScrollBar(false).release()), | 153 vert_sb_(PlatformStyle::CreateScrollBar(false).release()), |
151 corner_view_(new ScrollCornerView()), | 154 corner_view_(new ScrollCornerView()), |
152 min_height_(-1), | 155 min_height_(-1), |
153 max_height_(-1), | 156 max_height_(-1), |
154 background_color_(SK_ColorTRANSPARENT), | 157 background_color_(SK_ColorTRANSPARENT), |
155 hide_horizontal_scrollbar_(false) { | 158 hide_horizontal_scrollbar_(false), |
| 159 scroll_with_layers_enabled_( |
| 160 base::FeatureList::IsEnabled(kToolkitViewsScrollWithLayers)) { |
156 set_notify_enter_exit_on_child(true); | 161 set_notify_enter_exit_on_child(true); |
157 | 162 |
158 AddChildView(contents_viewport_); | 163 AddChildView(contents_viewport_); |
159 AddChildView(header_viewport_); | 164 AddChildView(header_viewport_); |
160 | 165 |
161 // Don't add the scrollbars as children until we discover we need them | 166 // Don't add the scrollbars as children until we discover we need them |
162 // (ShowOrHideScrollBar). | 167 // (ShowOrHideScrollBar). |
163 horiz_sb_->SetVisible(false); | 168 horiz_sb_->SetVisible(false); |
164 horiz_sb_->set_controller(this); | 169 horiz_sb_->set_controller(this); |
165 vert_sb_->SetVisible(false); | 170 vert_sb_->SetVisible(false); |
166 vert_sb_->set_controller(this); | 171 vert_sb_->set_controller(this); |
167 corner_view_->SetVisible(false); | 172 corner_view_->SetVisible(false); |
168 | 173 |
169 if (!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 && !viewport_layer_enabled_ && Contains(details.parent)) |
| 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 |