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 "base/threading/thread_task_runner_handle.h" |
10 #include "ui/base/material_design/material_design_controller.h" | 11 #include "ui/base/material_design/material_design_controller.h" |
11 #include "ui/events/event.h" | 12 #include "ui/events/event.h" |
12 #include "ui/gfx/canvas.h" | 13 #include "ui/gfx/canvas.h" |
13 #include "ui/native_theme/native_theme.h" | 14 #include "ui/native_theme/native_theme.h" |
14 #include "ui/views/background.h" | 15 #include "ui/views/background.h" |
15 #include "ui/views/border.h" | 16 #include "ui/views/border.h" |
16 #include "ui/views/controls/focus_ring.h" | 17 #include "ui/views/controls/focus_ring.h" |
17 #include "ui/views/style/platform_style.h" | 18 #include "ui/views/style/platform_style.h" |
18 #include "ui/views/widget/widget.h" | 19 #include "ui/views/widget/widget.h" |
19 | 20 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 int max = std::max(content_size - viewport_size, 0); | 56 int max = std::max(content_size - viewport_size, 0); |
56 if (current_pos < 0) | 57 if (current_pos < 0) |
57 return 0; | 58 return 0; |
58 if (current_pos > max) | 59 if (current_pos > max) |
59 return max; | 60 return max; |
60 return current_pos; | 61 return current_pos; |
61 } | 62 } |
62 | 63 |
63 // Make sure the content is not scrolled out of bounds | 64 // Make sure the content is not scrolled out of bounds |
64 void ConstrainScrollToBounds(View* viewport, View* view) { | 65 void ConstrainScrollToBounds(View* viewport, View* view) { |
65 if (!view) | 66 if (!view || !view->layer()) |
66 return; | 67 return; |
67 | 68 |
68 // Note that even when ScrollView::ScrollsWithLayers() is true, the header row | 69 // Note that even when ScrollView::ScrollsWithLayers() is true, the header row |
69 // scrolls by repainting. | 70 // scrolls by repainting. |
70 const bool scrolls_with_layers = viewport->layer() != nullptr; | 71 const bool scrolls_with_layers = viewport->layer() != nullptr; |
71 if (scrolls_with_layers) { | 72 if (scrolls_with_layers) { |
72 DCHECK(view->layer()); | 73 DCHECK(view->layer()); |
73 DCHECK_EQ(0, view->x()); | 74 DCHECK_EQ(0, view->x()); |
74 DCHECK_EQ(0, view->y()); | 75 DCHECK_EQ(0, view->y()); |
75 } | 76 } |
(...skipping 19 matching lines...) Expand all Loading... |
95 int content_size, | 96 int content_size, |
96 int viewport_size) { | 97 int viewport_size) { |
97 if (-current_position == new_position) | 98 if (-current_position == new_position) |
98 return new_position; | 99 return new_position; |
99 if (new_position < 0) | 100 if (new_position < 0) |
100 return 0; | 101 return 0; |
101 const int max_position = std::max(0, content_size - viewport_size); | 102 const int max_position = std::max(0, content_size - viewport_size); |
102 return (new_position > max_position) ? max_position : new_position; | 103 return (new_position > max_position) ? max_position : new_position; |
103 } | 104 } |
104 | 105 |
| 106 // Set if the kToolkitViewsScrollWithLayers feature is enabled. |
| 107 // TODO(ananta) |
| 108 // Remove this when the feature is enabled by default. |
| 109 bool g_scroll_with_layers_enabled = false; |
| 110 |
105 } // namespace | 111 } // namespace |
106 | 112 |
107 // Viewport contains the contents View of the ScrollView. | 113 // Viewport contains the contents View of the ScrollView. |
108 class ScrollView::Viewport : public View { | 114 class ScrollView::Viewport : public View { |
109 public: | 115 public: |
110 Viewport() {} | 116 Viewport() {} |
111 ~Viewport() override {} | 117 ~Viewport() override {} |
112 | 118 |
113 const char* GetClassName() const override { return "ScrollView::Viewport"; } | 119 const char* GetClassName() const override { return "ScrollView::Viewport"; } |
114 | 120 |
(...skipping 30 matching lines...) Expand all Loading... |
145 : contents_(NULL), | 151 : contents_(NULL), |
146 contents_viewport_(new Viewport()), | 152 contents_viewport_(new Viewport()), |
147 header_(NULL), | 153 header_(NULL), |
148 header_viewport_(new Viewport()), | 154 header_viewport_(new Viewport()), |
149 horiz_sb_(PlatformStyle::CreateScrollBar(true).release()), | 155 horiz_sb_(PlatformStyle::CreateScrollBar(true).release()), |
150 vert_sb_(PlatformStyle::CreateScrollBar(false).release()), | 156 vert_sb_(PlatformStyle::CreateScrollBar(false).release()), |
151 corner_view_(new ScrollCornerView()), | 157 corner_view_(new ScrollCornerView()), |
152 min_height_(-1), | 158 min_height_(-1), |
153 max_height_(-1), | 159 max_height_(-1), |
154 background_color_(SK_ColorTRANSPARENT), | 160 background_color_(SK_ColorTRANSPARENT), |
155 hide_horizontal_scrollbar_(false) { | 161 hide_horizontal_scrollbar_(false), |
| 162 weak_ptr_factory_(this) { |
156 set_notify_enter_exit_on_child(true); | 163 set_notify_enter_exit_on_child(true); |
157 | 164 |
158 AddChildView(contents_viewport_); | 165 AddChildView(contents_viewport_); |
159 AddChildView(header_viewport_); | 166 AddChildView(header_viewport_); |
160 | 167 |
161 // Don't add the scrollbars as children until we discover we need them | 168 // Don't add the scrollbars as children until we discover we need them |
162 // (ShowOrHideScrollBar). | 169 // (ShowOrHideScrollBar). |
163 horiz_sb_->SetVisible(false); | 170 horiz_sb_->SetVisible(false); |
164 horiz_sb_->set_controller(this); | 171 horiz_sb_->set_controller(this); |
165 vert_sb_->SetVisible(false); | 172 vert_sb_->SetVisible(false); |
166 vert_sb_->set_controller(this); | 173 vert_sb_->set_controller(this); |
167 corner_view_->SetVisible(false); | 174 corner_view_->SetVisible(false); |
168 | 175 |
169 if (!base::FeatureList::IsEnabled(kToolkitViewsScrollWithLayers)) | 176 g_scroll_with_layers_enabled = |
| 177 base::FeatureList::IsEnabled(kToolkitViewsScrollWithLayers); |
| 178 if (!g_scroll_with_layers_enabled) |
170 return; | 179 return; |
| 180 |
171 EnableViewPortLayer(); | 181 EnableViewPortLayer(); |
172 } | 182 } |
173 | 183 |
174 ScrollView::~ScrollView() { | 184 ScrollView::~ScrollView() { |
175 // The scrollbars may not have been added, delete them to ensure they get | 185 // The scrollbars may not have been added, delete them to ensure they get |
176 // deleted. | 186 // deleted. |
177 delete horiz_sb_; | 187 delete horiz_sb_; |
178 delete vert_sb_; | 188 delete vert_sb_; |
179 delete corner_view_; | 189 delete corner_view_; |
180 } | 190 } |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 } | 530 } |
521 | 531 |
522 const char* ScrollView::GetClassName() const { | 532 const char* ScrollView::GetClassName() const { |
523 return kViewClassName; | 533 return kViewClassName; |
524 } | 534 } |
525 | 535 |
526 void ScrollView::OnNativeThemeChanged(const ui::NativeTheme* theme) { | 536 void ScrollView::OnNativeThemeChanged(const ui::NativeTheme* theme) { |
527 UpdateBorder(); | 537 UpdateBorder(); |
528 } | 538 } |
529 | 539 |
| 540 void ScrollView::ChildLayerAdded() { |
| 541 EnableViewPortLayer(); |
| 542 } |
| 543 |
530 void ScrollView::ScrollToPosition(ScrollBar* source, int position) { | 544 void ScrollView::ScrollToPosition(ScrollBar* source, int position) { |
531 if (!contents_) | 545 if (!contents_) |
532 return; | 546 return; |
533 | 547 |
534 gfx::ScrollOffset offset = CurrentOffset(); | 548 gfx::ScrollOffset offset = CurrentOffset(); |
535 if (source == horiz_sb_ && horiz_sb_->visible()) { | 549 if (source == horiz_sb_ && horiz_sb_->visible()) { |
536 position = AdjustPosition(offset.x(), position, contents_->width(), | 550 position = AdjustPosition(offset.x(), position, contents_->width(), |
537 contents_viewport_->width()); | 551 contents_viewport_->width()); |
538 if (offset.x() == position) | 552 if (offset.x() == position) |
539 return; | 553 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. | 724 // and commits a frame, which isn't true in some tests. |
711 // See http://crbug.com/637521. | 725 // See http://crbug.com/637521. |
712 OnLayerScrolled(offset); | 726 OnLayerScrolled(offset); |
713 } else { | 727 } else { |
714 contents_->SetPosition(gfx::Point(-offset.x(), -offset.y())); | 728 contents_->SetPosition(gfx::Point(-offset.x(), -offset.y())); |
715 ScrollHeader(); | 729 ScrollHeader(); |
716 } | 730 } |
717 } | 731 } |
718 | 732 |
719 bool ScrollView::ScrollsWithLayers() const { | 733 bool ScrollView::ScrollsWithLayers() const { |
| 734 if (!g_scroll_with_layers_enabled) |
| 735 return false; |
720 // Just check for the presence of a layer since it's cheaper than querying the | 736 // Just check for the presence of a layer since it's cheaper than querying the |
721 // Feature flag each time. | 737 // Feature flag each time. |
722 return contents_viewport_->layer() != nullptr; | 738 return contents_viewport_->layer() != nullptr; |
723 } | 739 } |
724 | 740 |
725 void ScrollView::EnableViewPortLayer() { | 741 void ScrollView::EnableViewPortLayer() { |
| 742 if (viewport_layer_enabled_) |
| 743 return; |
| 744 |
| 745 viewport_layer_enabled_ = true; |
726 background_color_ = SK_ColorWHITE; | 746 background_color_ = SK_ColorWHITE; |
727 contents_viewport_->set_background( | 747 contents_viewport_->set_background( |
728 Background::CreateSolidBackground(background_color_)); | 748 Background::CreateSolidBackground(background_color_)); |
729 contents_viewport_->SetPaintToLayer(); | 749 contents_viewport_->SetPaintToLayer(); |
730 contents_viewport_->layer()->SetMasksToBounds(true); | 750 contents_viewport_->layer()->SetMasksToBounds(true); |
731 } | 751 } |
732 | 752 |
733 void ScrollView::OnLayerScrolled(const gfx::ScrollOffset&) { | 753 void ScrollView::OnLayerScrolled(const gfx::ScrollOffset&) { |
734 UpdateScrollBarPositions(); | 754 UpdateScrollBarPositions(); |
735 ScrollHeader(); | 755 ScrollHeader(); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 | 850 |
831 VariableRowHeightScrollHelper::RowInfo | 851 VariableRowHeightScrollHelper::RowInfo |
832 FixedRowHeightScrollHelper::GetRowInfo(int y) { | 852 FixedRowHeightScrollHelper::GetRowInfo(int y) { |
833 if (y < top_margin_) | 853 if (y < top_margin_) |
834 return RowInfo(0, top_margin_); | 854 return RowInfo(0, top_margin_); |
835 return RowInfo((y - top_margin_) / row_height_ * row_height_ + top_margin_, | 855 return RowInfo((y - top_margin_) / row_height_ * row_height_ + top_margin_, |
836 row_height_); | 856 row_height_); |
837 } | 857 } |
838 | 858 |
839 } // namespace views | 859 } // namespace views |
OLD | NEW |