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