| 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 |