Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: ui/views/controls/scroll_view.cc

Issue 2188133002: Scroll with Layers in views::ScrollView (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@20160728-MacViews-ScrollTrack
Patch Set: DCHECK for no layer Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/views/controls/scroll_view.h ('k') | ui/views/controls/scroll_view_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/logging.h" 8 #include "base/logging.h"
8 #include "base/macros.h" 9 #include "base/macros.h"
9 #include "ui/events/event.h" 10 #include "ui/events/event.h"
10 #include "ui/gfx/canvas.h" 11 #include "ui/gfx/canvas.h"
11 #include "ui/native_theme/native_theme.h" 12 #include "ui/native_theme/native_theme.h"
13 #include "ui/views/background.h"
12 #include "ui/views/border.h" 14 #include "ui/views/border.h"
13 #include "ui/views/style/platform_style.h" 15 #include "ui/views/style/platform_style.h"
14 #include "ui/views/widget/root_view.h" 16 #include "ui/views/widget/widget.h"
15 17
16 namespace views { 18 namespace views {
17 19
18 const char ScrollView::kViewClassName[] = "ScrollView"; 20 const char ScrollView::kViewClassName[] = "ScrollView";
19 21
20 namespace { 22 namespace {
21 23
24 const base::Feature kToolkitViewsScrollWithLayers {
25 "ToolkitViewsScrollWithLayers",
26 #if defined(OS_MACOSX)
27 base::FEATURE_ENABLED_BY_DEFAULT
28 #else
29 base::FEATURE_DISABLED_BY_DEFAULT
30 #endif
31 };
32
22 // Subclass of ScrollView that resets the border when the theme changes. 33 // Subclass of ScrollView that resets the border when the theme changes.
23 class ScrollViewWithBorder : public views::ScrollView { 34 class ScrollViewWithBorder : public views::ScrollView {
24 public: 35 public:
25 ScrollViewWithBorder() {} 36 ScrollViewWithBorder() {}
26 37
27 // View overrides; 38 // View overrides;
28 void OnNativeThemeChanged(const ui::NativeTheme* theme) override { 39 void OnNativeThemeChanged(const ui::NativeTheme* theme) override {
29 SetBorder(Border::CreateSolidBorder( 40 SetBorder(Border::CreateSolidBorder(
30 1, 41 1,
31 theme->GetSystemColor(ui::NativeTheme::kColorId_UnfocusedBorderColor))); 42 theme->GetSystemColor(ui::NativeTheme::kColorId_UnfocusedBorderColor)));
(...skipping 25 matching lines...) Expand all
57 int CheckScrollBounds(int viewport_size, int content_size, int current_pos) { 68 int CheckScrollBounds(int viewport_size, int content_size, int current_pos) {
58 int max = std::max(content_size - viewport_size, 0); 69 int max = std::max(content_size - viewport_size, 0);
59 if (current_pos < 0) 70 if (current_pos < 0)
60 return 0; 71 return 0;
61 if (current_pos > max) 72 if (current_pos > max)
62 return max; 73 return max;
63 return current_pos; 74 return current_pos;
64 } 75 }
65 76
66 // Make sure the content is not scrolled out of bounds 77 // Make sure the content is not scrolled out of bounds
67 void CheckScrollBounds(View* viewport, View* view) { 78 void CheckScrollBounds(View* viewport, View* container, View* view) {
68 if (!view) 79 if (!view)
69 return; 80 return;
70 81
71 int x = CheckScrollBounds(viewport->width(), view->width(), -view->x()); 82 gfx::ScrollOffset offset = container
72 int y = CheckScrollBounds(viewport->height(), view->height(), -view->y()); 83 ? container->layer()->CurrentScrollOffset()
84 : gfx::ScrollOffset(-view->x(), -view->y());
73 85
74 // This is no op if bounds are the same 86 int x = CheckScrollBounds(viewport->width(), view->width(), offset.x());
75 view->SetBounds(-x, -y, view->width(), view->height()); 87 int y = CheckScrollBounds(viewport->height(), view->height(), offset.y());
88
89 if (container) {
90 container->layer()->SetScrollOffset(gfx::ScrollOffset(x, y));
91 } else {
92 // This is no op if bounds are the same
93 view->SetBounds(-x, -y, view->width(), view->height());
94 }
76 } 95 }
77 96
78 // Used by ScrollToPosition() to make sure the new position fits within the 97 // Used by ScrollToPosition() to make sure the new position fits within the
79 // allowed scroll range. 98 // allowed scroll range.
80 int AdjustPosition(int current_position, 99 int AdjustPosition(int current_position,
81 int new_position, 100 int new_position,
82 int content_size, 101 int content_size,
83 int viewport_size) { 102 int viewport_size) {
84 if (-current_position == new_position) 103 if (-current_position == new_position)
85 return new_position; 104 return new_position;
86 if (new_position < 0) 105 if (new_position < 0)
87 return 0; 106 return 0;
88 const int max_position = std::max(0, content_size - viewport_size); 107 const int max_position = std::max(0, content_size - viewport_size);
89 return (new_position > max_position) ? max_position : new_position; 108 return (new_position > max_position) ? max_position : new_position;
90 } 109 }
91 110
111 class ScrollViewContainer : public View {
112 public:
113 ScrollViewContainer() {}
114
115 // View:
116 void ChildPreferredSizeChanged(View* child) override {
117 PreferredSizeChanged();
118 }
119
120 private:
121 DISALLOW_COPY_AND_ASSIGN(ScrollViewContainer);
122 };
123
92 } // namespace 124 } // namespace
93 125
94 // Viewport contains the contents View of the ScrollView. 126 // Viewport contains the contents View of the ScrollView.
95 class ScrollView::Viewport : public View { 127 class ScrollView::Viewport : public View {
96 public: 128 public:
97 Viewport() {} 129 Viewport() {}
98 ~Viewport() override {} 130 ~Viewport() override {}
99 131
100 const char* GetClassName() const override { return "ScrollView::Viewport"; } 132 const char* GetClassName() const override { return "ScrollView::Viewport"; }
101 133
102 void ScrollRectToVisible(const gfx::Rect& rect) override { 134 void ScrollRectToVisible(const gfx::Rect& rect) override {
103 if (!has_children() || !parent()) 135 if (!has_children() || !parent())
104 return; 136 return;
105 137
106 View* contents = child_at(0); 138 View* contents = child_at(0);
107 gfx::Rect scroll_rect(rect); 139 gfx::Rect scroll_rect(rect);
108 scroll_rect.Offset(-contents->x(), -contents->y()); 140
109 static_cast<ScrollView*>(parent())->ScrollContentsRegionToBeVisible( 141 ScrollView* scroll_view = static_cast<ScrollView*>(parent());
110 scroll_rect); 142 if (contents == scroll_view->contents_container_) {
143 // With layer scrolling, there's no need to "undo" the offset done in the
144 // child's View::ScrollRectToVisible() before it calls this.
145 DCHECK_EQ(0, contents->x());
146 DCHECK_EQ(0, contents->y());
147 } else {
148 scroll_rect.Offset(-contents->x(), -contents->y());
149 }
150
151 scroll_view->ScrollContentsRegionToBeVisible(scroll_rect);
111 } 152 }
112 153
113 void ChildPreferredSizeChanged(View* child) override { 154 void ChildPreferredSizeChanged(View* child) override {
114 if (parent()) 155 if (parent())
115 parent()->Layout(); 156 parent()->Layout();
116 } 157 }
117 158
118 private: 159 private:
119 DISALLOW_COPY_AND_ASSIGN(Viewport); 160 DISALLOW_COPY_AND_ASSIGN(Viewport);
120 }; 161 };
121 162
122 ScrollView::ScrollView() 163 ScrollView::ScrollView()
123 : contents_(NULL), 164 : contents_(NULL),
165 contents_container_(nullptr),
124 contents_viewport_(new Viewport()), 166 contents_viewport_(new Viewport()),
125 header_(NULL), 167 header_(NULL),
126 header_viewport_(new Viewport()), 168 header_viewport_(new Viewport()),
127 horiz_sb_(PlatformStyle::CreateScrollBar(true).release()), 169 horiz_sb_(PlatformStyle::CreateScrollBar(true).release()),
128 vert_sb_(PlatformStyle::CreateScrollBar(false).release()), 170 vert_sb_(PlatformStyle::CreateScrollBar(false).release()),
129 corner_view_(new ScrollCornerView()), 171 corner_view_(new ScrollCornerView()),
130 min_height_(-1), 172 min_height_(-1),
131 max_height_(-1), 173 max_height_(-1),
132 hide_horizontal_scrollbar_(false) { 174 hide_horizontal_scrollbar_(false) {
133 set_notify_enter_exit_on_child(true); 175 set_notify_enter_exit_on_child(true);
134 176
135 AddChildView(contents_viewport_); 177 AddChildView(contents_viewport_);
136 AddChildView(header_viewport_); 178 AddChildView(header_viewport_);
137 179
138 // Don't add the scrollbars as children until we discover we need them 180 // Don't add the scrollbars as children until we discover we need them
139 // (ShowOrHideScrollBar). 181 // (ShowOrHideScrollBar).
140 horiz_sb_->SetVisible(false); 182 horiz_sb_->SetVisible(false);
141 horiz_sb_->set_controller(this); 183 horiz_sb_->set_controller(this);
142 vert_sb_->SetVisible(false); 184 vert_sb_->SetVisible(false);
143 vert_sb_->set_controller(this); 185 vert_sb_->set_controller(this);
144 corner_view_->SetVisible(false); 186 corner_view_->SetVisible(false);
187
188 if (!base::FeatureList::IsEnabled(kToolkitViewsScrollWithLayers))
189 return;
190
191 contents_container_ = new ScrollViewContainer();
192 contents_viewport_->AddChildView(contents_container_);
193 contents_viewport_->SetPaintToLayer(true);
194
195 // TODO(tapted): Support setting the background to something other than white,
tapted 2016/08/05 07:12:31 Without this TODO - the ExtensionInstall dialog wo
196 // if something ends up needing that.
197 contents_viewport_->set_background(
198 Background::CreateSolidBackground(SK_ColorWHITE));
199 contents_viewport_->layer()->SetMasksToBounds(true);
200
201 contents_container_->SetPaintToLayer(true);
202 contents_container_->set_background(
203 Background::CreateSolidBackground(SK_ColorWHITE));
204 contents_container_->layer()->SetScrollable(
205 contents_viewport_->layer(),
206 base::Bind(&ScrollView::OnLayerScrolled, base::Unretained(this)));
145 } 207 }
146 208
147 ScrollView::~ScrollView() { 209 ScrollView::~ScrollView() {
148 // The scrollbars may not have been added, delete them to ensure they get 210 // The scrollbars may not have been added, delete them to ensure they get
149 // deleted. 211 // deleted.
150 delete horiz_sb_; 212 delete horiz_sb_;
151 delete vert_sb_; 213 delete vert_sb_;
152 delete corner_view_; 214 delete corner_view_;
153 } 215 }
154 216
155 // static 217 // static
156 ScrollView* ScrollView::CreateScrollViewWithBorder() { 218 ScrollView* ScrollView::CreateScrollViewWithBorder() {
157 return new ScrollViewWithBorder(); 219 return new ScrollViewWithBorder();
158 } 220 }
159 221
160 void ScrollView::SetContents(View* a_view) { 222 void ScrollView::SetContents(View* a_view) {
161 SetHeaderOrContents(contents_viewport_, a_view, &contents_); 223 // Protect against clients passing a contents view that has its own Layer.
224 // While this will probably work, it's wasteful since its container will have
225 // a layer of its own.
226 DCHECK(!a_view->layer());
tapted 2016/08/04 13:19:01 added a dcheck here per the comments in the overvi
227 View* parent = contents_container_ ? contents_container_ : contents_viewport_;
228 SetHeaderOrContents(parent, a_view, &contents_);
162 } 229 }
163 230
164 void ScrollView::SetHeader(View* header) { 231 void ScrollView::SetHeader(View* header) {
165 SetHeaderOrContents(header_viewport_, header, &header_); 232 SetHeaderOrContents(header_viewport_, header, &header_);
166 } 233 }
167 234
168 gfx::Rect ScrollView::GetVisibleRect() const { 235 gfx::Rect ScrollView::GetVisibleRect() const {
169 if (!contents_) 236 if (!contents_)
170 return gfx::Rect(); 237 return gfx::Rect();
171 return gfx::Rect(-contents_->x(), -contents_->y(), 238 gfx::ScrollOffset offset = CurrentOffset();
172 contents_viewport_->width(), contents_viewport_->height()); 239 return gfx::Rect(offset.x(), offset.y(), contents_viewport_->width(),
240 contents_viewport_->height());
173 } 241 }
174 242
175 void ScrollView::ClipHeightTo(int min_height, int max_height) { 243 void ScrollView::ClipHeightTo(int min_height, int max_height) {
176 min_height_ = min_height; 244 min_height_ = min_height;
177 max_height_ = max_height; 245 max_height_ = max_height;
178 } 246 }
179 247
180 int ScrollView::GetScrollBarWidth() const { 248 int ScrollView::GetScrollBarWidth() const {
181 return vert_sb_ ? vert_sb_->GetLayoutSize() : 0; 249 return vert_sb_ ? vert_sb_->GetLayoutSize() : 0;
182 } 250 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 // viewport_size is the total client space available. 328 // viewport_size is the total client space available.
261 gfx::Size viewport_size = viewport_bounds.size(); 329 gfx::Size viewport_size = viewport_bounds.size();
262 // Assumes a vertical scrollbar since most of the current views are designed 330 // Assumes a vertical scrollbar since most of the current views are designed
263 // for this. 331 // for this.
264 int horiz_sb_height = GetScrollBarHeight(); 332 int horiz_sb_height = GetScrollBarHeight();
265 int vert_sb_width = GetScrollBarWidth(); 333 int vert_sb_width = GetScrollBarWidth();
266 viewport_bounds.set_width(viewport_bounds.width() - vert_sb_width); 334 viewport_bounds.set_width(viewport_bounds.width() - vert_sb_width);
267 // Update the bounds right now so the inner views can fit in it. 335 // Update the bounds right now so the inner views can fit in it.
268 contents_viewport_->SetBoundsRect(viewport_bounds); 336 contents_viewport_->SetBoundsRect(viewport_bounds);
269 337
270 // Give |contents_| a chance to update its bounds if it depends on the 338 // Give |contents_| a chance to update its bounds if it depends on its parent
271 // viewport. 339 // bounds.
272 if (contents_) 340 if (contents_) {
341 // The container bounds may need to be made larger later, but use the
342 // viewport bounds to layout the contents.
343 if (contents_container_)
344 contents_container_->SetBoundsRect(viewport_bounds);
273 contents_->Layout(); 345 contents_->Layout();
346 }
274 347
275 bool should_layout_contents = false; 348 bool should_layout_contents = false;
276 bool horiz_sb_required = false; 349 bool horiz_sb_required = false;
277 bool vert_sb_required = false; 350 bool vert_sb_required = false;
278 if (contents_) { 351 if (contents_) {
279 gfx::Size content_size = contents_->size(); 352 gfx::Size content_size = contents_->size();
280 ComputeScrollBarsVisibility(viewport_size, 353 ComputeScrollBarsVisibility(viewport_size,
281 content_size, 354 content_size,
282 &horiz_sb_required, 355 &horiz_sb_required,
283 &vert_sb_required); 356 &vert_sb_required);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 viewport_bounds.bottom() - contents_y - height_offset); 392 viewport_bounds.bottom() - contents_y - height_offset);
320 } 393 }
321 if (corner_view_required) { 394 if (corner_view_required) {
322 // Show the resize corner. 395 // Show the resize corner.
323 corner_view_->SetBounds(vert_sb_->bounds().x(), horiz_sb_->bounds().y(), 396 corner_view_->SetBounds(vert_sb_->bounds().x(), horiz_sb_->bounds().y(),
324 vert_sb_width, horiz_sb_height); 397 vert_sb_width, horiz_sb_height);
325 } 398 }
326 399
327 // Update to the real client size with the visible scrollbars. 400 // Update to the real client size with the visible scrollbars.
328 contents_viewport_->SetBoundsRect(viewport_bounds); 401 contents_viewport_->SetBoundsRect(viewport_bounds);
329 if (should_layout_contents && contents_) 402 if (should_layout_contents && contents_) {
403 if (contents_container_)
404 contents_container_->SetBoundsRect(viewport_bounds);
330 contents_->Layout(); 405 contents_->Layout();
406 }
407
408 // Even when |contents_| needs to scroll, it can still be narrower or wider
409 // the viewport. So ensure the scrolling layer can fill the viewport, so that
410 // events will correctly hit it, and overscroll looks correct.
411 if (contents_container_) {
412 gfx::Size container_size = contents_ ? contents_->size() : gfx::Size();
413 container_size.SetToMax(viewport_bounds.size());
414 contents_container_->SetBoundsRect(gfx::Rect(container_size));
415 }
331 416
332 header_viewport_->SetBounds(contents_x, contents_y, 417 header_viewport_->SetBounds(contents_x, contents_y,
333 viewport_bounds.width(), header_height); 418 viewport_bounds.width(), header_height);
334 if (header_) 419 if (header_)
335 header_->Layout(); 420 header_->Layout();
336 421
337 CheckScrollBounds(header_viewport_, header_); 422 CheckScrollBounds(header_viewport_, nullptr, header_);
338 CheckScrollBounds(contents_viewport_, contents_); 423 CheckScrollBounds(contents_viewport_, contents_container_, contents_);
424
339 SchedulePaint(); 425 SchedulePaint();
340 UpdateScrollBarPositions(); 426 UpdateScrollBarPositions();
341 } 427 }
342 428
343 bool ScrollView::OnKeyPressed(const ui::KeyEvent& event) { 429 bool ScrollView::OnKeyPressed(const ui::KeyEvent& event) {
344 bool processed = false; 430 bool processed = false;
345 431
346 // Give vertical scrollbar priority 432 // Give vertical scrollbar priority
347 if (vert_sb_->visible()) 433 if (vert_sb_->visible())
348 processed = vert_sb_->OnKeyPressed(event); 434 processed = vert_sb_->OnKeyPressed(event);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 if (!event->handled() && horiz_sb_->visible()) { 481 if (!event->handled() && horiz_sb_->visible()) {
396 if (horiz_sb_->bounds().Contains(event->location()) || scroll_event) 482 if (horiz_sb_->bounds().Contains(event->location()) || scroll_event)
397 horiz_sb_->OnGestureEvent(event); 483 horiz_sb_->OnGestureEvent(event);
398 } 484 }
399 } 485 }
400 486
401 const char* ScrollView::GetClassName() const { 487 const char* ScrollView::GetClassName() const {
402 return kViewClassName; 488 return kViewClassName;
403 } 489 }
404 490
491 ScrollView* ScrollView::EnclosingScrollView() {
492 return this;
493 }
494
405 void ScrollView::ScrollToPosition(ScrollBar* source, int position) { 495 void ScrollView::ScrollToPosition(ScrollBar* source, int position) {
406 if (!contents_) 496 if (!contents_)
407 return; 497 return;
408 498
499 gfx::ScrollOffset offset = CurrentOffset();
409 if (source == horiz_sb_ && horiz_sb_->visible()) { 500 if (source == horiz_sb_ && horiz_sb_->visible()) {
410 position = AdjustPosition(contents_->x(), position, contents_->width(), 501 position = AdjustPosition(offset.x(), position, contents_->width(),
411 contents_viewport_->width()); 502 contents_viewport_->width());
412 if (-contents_->x() == position) 503 if (offset.x() == position)
413 return; 504 return;
414 contents_->SetX(-position); 505 offset.set_x(position);
415 if (header_) {
416 header_->SetX(-position);
417 header_->SchedulePaintInRect(header_->GetVisibleBounds());
418 }
419 } else if (source == vert_sb_ && vert_sb_->visible()) { 506 } else if (source == vert_sb_ && vert_sb_->visible()) {
420 position = AdjustPosition(contents_->y(), position, contents_->height(), 507 position = AdjustPosition(offset.y(), position, contents_->height(),
421 contents_viewport_->height()); 508 contents_viewport_->height());
422 if (-contents_->y() == position) 509 if (offset.y() == position)
423 return; 510 return;
424 contents_->SetY(-position); 511 offset.set_y(position);
425 } 512 }
426 contents_->SchedulePaintInRect(contents_->GetVisibleBounds()); 513 ScrollToOffset(offset);
514
515 if (!contents_container_)
516 contents_->SchedulePaintInRect(contents_->GetVisibleBounds());
427 } 517 }
428 518
429 int ScrollView::GetScrollIncrement(ScrollBar* source, bool is_page, 519 int ScrollView::GetScrollIncrement(ScrollBar* source, bool is_page,
430 bool is_positive) { 520 bool is_positive) {
431 bool is_horizontal = source->IsHorizontal(); 521 bool is_horizontal = source->IsHorizontal();
432 int amount = 0; 522 int amount = 0;
433 if (contents_) { 523 if (contents_) {
434 if (is_page) { 524 if (is_page) {
435 amount = contents_->GetPageScrollIncrement( 525 amount = contents_->GetPageScrollIncrement(
436 this, is_horizontal, is_positive); 526 this, is_horizontal, is_positive);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 // corner. This is done by setting the offset to -X or -Y. For down 587 // corner. This is done by setting the offset to -X or -Y. For down
498 // or right shifts we need to make sure it appears in the 588 // or right shifts we need to make sure it appears in the
499 // lower/right corner. This is calculated by taking max_x or max_y 589 // lower/right corner. This is calculated by taking max_x or max_y
500 // and scaling it back by the size of the viewport. 590 // and scaling it back by the size of the viewport.
501 const int new_x = 591 const int new_x =
502 (vis_rect.x() > x) ? x : std::max(0, max_x - contents_viewport_->width()); 592 (vis_rect.x() > x) ? x : std::max(0, max_x - contents_viewport_->width());
503 const int new_y = 593 const int new_y =
504 (vis_rect.y() > y) ? y : std::max(0, max_y - 594 (vis_rect.y() > y) ? y : std::max(0, max_y -
505 contents_viewport_->height()); 595 contents_viewport_->height());
506 596
507 contents_->SetX(-new_x); 597 ScrollToOffset(gfx::ScrollOffset(new_x, new_y));
508 if (header_)
509 header_->SetX(-new_x);
510 contents_->SetY(-new_y);
511 UpdateScrollBarPositions(); 598 UpdateScrollBarPositions();
512 } 599 }
513 600
514 void ScrollView::ComputeScrollBarsVisibility(const gfx::Size& vp_size, 601 void ScrollView::ComputeScrollBarsVisibility(const gfx::Size& vp_size,
515 const gfx::Size& content_size, 602 const gfx::Size& content_size,
516 bool* horiz_is_shown, 603 bool* horiz_is_shown,
517 bool* vert_is_shown) const { 604 bool* vert_is_shown) const {
518 // Try to fit both ways first, then try vertical bar only, then horizontal 605 // Try to fit both ways first, then try vertical bar only, then horizontal
519 // bar only, then defaults to both shown. 606 // bar only, then defaults to both shown.
520 if (content_size.width() <= vp_size.width() && 607 if (content_size.width() <= vp_size.width() &&
(...skipping 27 matching lines...) Expand all
548 } else { 635 } else {
549 RemoveChildView(control); 636 RemoveChildView(control);
550 control->SetVisible(false); 637 control->SetVisible(false);
551 } 638 }
552 } 639 }
553 640
554 void ScrollView::UpdateScrollBarPositions() { 641 void ScrollView::UpdateScrollBarPositions() {
555 if (!contents_) 642 if (!contents_)
556 return; 643 return;
557 644
645 const gfx::ScrollOffset offset = CurrentOffset();
558 if (horiz_sb_->visible()) { 646 if (horiz_sb_->visible()) {
559 int vw = contents_viewport_->width(); 647 int vw = contents_viewport_->width();
560 int cw = contents_->width(); 648 int cw = contents_->width();
561 int origin = contents_->x(); 649 horiz_sb_->Update(vw, cw, offset.x());
562 horiz_sb_->Update(vw, cw, -origin);
563 } 650 }
564 if (vert_sb_->visible()) { 651 if (vert_sb_->visible()) {
565 int vh = contents_viewport_->height(); 652 int vh = contents_viewport_->height();
566 int ch = contents_->height(); 653 int ch = contents_->height();
567 int origin = contents_->y(); 654 vert_sb_->Update(vh, ch, offset.y());
568 vert_sb_->Update(vh, ch, -origin);
569 } 655 }
570 } 656 }
571 657
658 gfx::ScrollOffset ScrollView::CurrentOffset() const {
659 if (contents_container_)
660 return contents_container_->layer()->CurrentScrollOffset();
661 return gfx::ScrollOffset(-contents_->x(), -contents_->y());
662 }
663
664 void ScrollView::ScrollToOffset(const gfx::ScrollOffset& offset) {
665 if (contents_container_) {
666 contents_container_->layer()->SetScrollOffset(offset);
667
668 // TODO(tapted): Remove this call to OnLayerScrolled(). It's unnecessary,
669 // but will only be invoked (asynchronously) when a Compositor is present
670 // and commits a frame, which isn't true in some tests.
671 OnLayerScrolled();
672 } else {
673 contents_->SetPosition(gfx::Point(-offset.x(), -offset.y()));
674 ScrollHeader();
675 }
676 }
677
678 void ScrollView::OnLayerScrolled() {
679 UpdateScrollBarPositions();
680 ScrollHeader();
681 }
682
683 void ScrollView::ScrollHeader() {
684 if (!header_)
685 return;
686
687 int x_offset = CurrentOffset().x();
688 if (header_->x() != -x_offset) {
689 header_->SetX(-x_offset);
690 header_->SchedulePaintInRect(header_->GetVisibleBounds());
691 }
692 }
693
572 // VariableRowHeightScrollHelper ---------------------------------------------- 694 // VariableRowHeightScrollHelper ----------------------------------------------
573 695
574 VariableRowHeightScrollHelper::VariableRowHeightScrollHelper( 696 VariableRowHeightScrollHelper::VariableRowHeightScrollHelper(
575 Controller* controller) : controller_(controller) { 697 Controller* controller) : controller_(controller) {
576 } 698 }
577 699
578 VariableRowHeightScrollHelper::~VariableRowHeightScrollHelper() { 700 VariableRowHeightScrollHelper::~VariableRowHeightScrollHelper() {
579 } 701 }
580 702
581 int VariableRowHeightScrollHelper::GetPageScrollIncrement( 703 int VariableRowHeightScrollHelper::GetPageScrollIncrement(
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 758
637 VariableRowHeightScrollHelper::RowInfo 759 VariableRowHeightScrollHelper::RowInfo
638 FixedRowHeightScrollHelper::GetRowInfo(int y) { 760 FixedRowHeightScrollHelper::GetRowInfo(int y) {
639 if (y < top_margin_) 761 if (y < top_margin_)
640 return RowInfo(0, top_margin_); 762 return RowInfo(0, top_margin_);
641 return RowInfo((y - top_margin_) / row_height_ * row_height_ + top_margin_, 763 return RowInfo((y - top_margin_) / row_height_ * row_height_ + top_margin_,
642 row_height_); 764 row_height_);
643 } 765 }
644 766
645 } // namespace views 767 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/scroll_view.h ('k') | ui/views/controls/scroll_view_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698