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

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

Issue 1680613002: Adding momentum/overscroll to views:: ScrollViews Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix Tableview layout. aaaand I think we are done 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/logging.h" 7 #include "base/logging.h"
8 #include "base/macros.h" 8 #include "base/macros.h"
9 #include "ui/compositor/overscroll/ui_scroll_input_manager.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
22 // Subclass of ScrollView that resets the border when the theme changes. 24 // Subclass of ScrollView that resets the border when the theme changes.
23 class ScrollViewWithBorder : public views::ScrollView { 25 class ScrollViewWithBorder : public views::ScrollView {
24 public: 26 public:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 int CheckScrollBounds(int viewport_size, int content_size, int current_pos) { 59 int CheckScrollBounds(int viewport_size, int content_size, int current_pos) {
58 int max = std::max(content_size - viewport_size, 0); 60 int max = std::max(content_size - viewport_size, 0);
59 if (current_pos < 0) 61 if (current_pos < 0)
60 return 0; 62 return 0;
61 if (current_pos > max) 63 if (current_pos > max)
62 return max; 64 return max;
63 return current_pos; 65 return current_pos;
64 } 66 }
65 67
66 // Make sure the content is not scrolled out of bounds 68 // Make sure the content is not scrolled out of bounds
67 void CheckScrollBounds(View* viewport, View* view) { 69 void CheckScrollBounds(View* viewport, View* container, View* view) {
68 if (!view) 70 if (!view)
69 return; 71 return;
70 72
71 int x = CheckScrollBounds(viewport->width(), view->width(), -view->x()); 73 gfx::ScrollOffset offset = container
72 int y = CheckScrollBounds(viewport->height(), view->height(), -view->y()); 74 ? container->layer()->CurrentScrollOffset()
75 : gfx::ScrollOffset(-view->x(), -view->y());
73 76
74 // This is no op if bounds are the same 77 int x = CheckScrollBounds(viewport->width(), view->width(), offset.x());
75 view->SetBounds(-x, -y, view->width(), view->height()); 78 int y = CheckScrollBounds(viewport->height(), view->height(), offset.y());
79
80 if (container) {
81 container->layer()->SetScrollOffset(gfx::ScrollOffset(x, y));
82 } else {
83 // This is no op if bounds are the same
84 view->SetBounds(-x, -y, view->width(), view->height());
85 }
76 } 86 }
77 87
78 // Used by ScrollToPosition() to make sure the new position fits within the 88 // Used by ScrollToPosition() to make sure the new position fits within the
79 // allowed scroll range. 89 // allowed scroll range.
80 int AdjustPosition(int current_position, 90 int AdjustPosition(int current_position,
81 int new_position, 91 int new_position,
82 int content_size, 92 int content_size,
83 int viewport_size) { 93 int viewport_size) {
84 if (-current_position == new_position) 94 if (-current_position == new_position)
85 return new_position; 95 return new_position;
86 if (new_position < 0) 96 if (new_position < 0)
87 return 0; 97 return 0;
88 const int max_position = std::max(0, content_size - viewport_size); 98 const int max_position = std::max(0, content_size - viewport_size);
89 return (new_position > max_position) ? max_position : new_position; 99 return (new_position > max_position) ? max_position : new_position;
90 } 100 }
91 101
102 class ScrollViewContainer : public View {
103 public:
104 ScrollViewContainer() {}
105
106 // View:
107 void ChildPreferredSizeChanged(View* child) override {
108 PreferredSizeChanged();
109 }
110
111 // TODO: Add ScrollRectToVisible
112
113 private:
114 DISALLOW_COPY_AND_ASSIGN(ScrollViewContainer);
115 };
116
92 } // namespace 117 } // namespace
93 118
94 // Viewport contains the contents View of the ScrollView. 119 // Viewport contains the contents View of the ScrollView.
95 class ScrollView::Viewport : public View { 120 class ScrollView::Viewport : public View {
96 public: 121 public:
97 Viewport() {} 122 Viewport() {}
98 ~Viewport() override {} 123 ~Viewport() override {}
99 124
100 const char* GetClassName() const override { return "ScrollView::Viewport"; } 125 const char* GetClassName() const override { return "ScrollView::Viewport"; }
101 126
102 void ScrollRectToVisible(const gfx::Rect& rect) override { 127 void ScrollRectToVisible(const gfx::Rect& rect) override {
103 if (!has_children() || !parent()) 128 if (!has_children() || !parent())
104 return; 129 return;
105 130
106 View* contents = child_at(0); 131 View* contents = child_at(0);
107 gfx::Rect scroll_rect(rect); 132 gfx::Rect scroll_rect(rect);
133
134 ScrollView* scroll_view = static_cast<ScrollView*>(parent());
135 if (contents == scroll_view->contents_container_) {
136 // With layer scrolling, there's no need to "undo" the offset done in the
137 // child's View::ScrollRectToVisible() before it calls this.
138 DCHECK_EQ(0, contents->x());
139 DCHECK_EQ(0, contents->y());
140 }
141
108 scroll_rect.Offset(-contents->x(), -contents->y()); 142 scroll_rect.Offset(-contents->x(), -contents->y());
109 static_cast<ScrollView*>(parent())->ScrollContentsRegionToBeVisible( 143 scroll_view->ScrollContentsRegionToBeVisible(scroll_rect);
110 scroll_rect);
111 } 144 }
112 145
113 void ChildPreferredSizeChanged(View* child) override { 146 void ChildPreferredSizeChanged(View* child) override {
114 if (parent()) 147 if (parent())
115 parent()->Layout(); 148 parent()->Layout();
116 } 149 }
117 150
118 private: 151 private:
119 DISALLOW_COPY_AND_ASSIGN(Viewport); 152 DISALLOW_COPY_AND_ASSIGN(Viewport);
120 }; 153 };
121 154
122 ScrollView::ScrollView() 155 ScrollView::ScrollView()
123 : contents_(NULL), 156 : contents_(NULL),
157 contents_container_(new ScrollViewContainer()),
124 contents_viewport_(new Viewport()), 158 contents_viewport_(new Viewport()),
125 header_(NULL), 159 header_(NULL),
126 header_viewport_(new Viewport()), 160 header_viewport_(new Viewport()),
127 horiz_sb_(PlatformStyle::CreateScrollBar(true).release()), 161 horiz_sb_(PlatformStyle::CreateScrollBar(true).release()),
128 vert_sb_(PlatformStyle::CreateScrollBar(false).release()), 162 vert_sb_(PlatformStyle::CreateScrollBar(false).release()),
129 corner_view_(new ScrollCornerView()), 163 corner_view_(new ScrollCornerView()),
130 min_height_(-1), 164 min_height_(-1),
131 max_height_(-1), 165 max_height_(-1),
132 hide_horizontal_scrollbar_(false) { 166 hide_horizontal_scrollbar_(false) {
133 set_notify_enter_exit_on_child(true); 167 set_notify_enter_exit_on_child(true);
134 168
135 AddChildView(contents_viewport_); 169 AddChildView(contents_viewport_);
170 contents_viewport_->AddChildView(contents_container_);
136 AddChildView(header_viewport_); 171 AddChildView(header_viewport_);
137 172
138 // Don't add the scrollbars as children until we discover we need them 173 // Don't add the scrollbars as children until we discover we need them
139 // (ShowOrHideScrollBar). 174 // (ShowOrHideScrollBar).
140 horiz_sb_->SetVisible(false); 175 horiz_sb_->SetVisible(false);
141 horiz_sb_->set_controller(this); 176 horiz_sb_->set_controller(this);
142 vert_sb_->SetVisible(false); 177 vert_sb_->SetVisible(false);
143 vert_sb_->set_controller(this); 178 vert_sb_->set_controller(this);
144 corner_view_->SetVisible(false); 179 corner_view_->SetVisible(false);
180
181 contents_viewport_->SetPaintToLayer(true);
182 contents_viewport_->set_background(
183 Background::CreateSolidBackground(SK_ColorWHITE));
184 contents_viewport_->layer()->SetMasksToBounds(true);
185
186 contents_container_->SetPaintToLayer(true);
187 contents_container_->set_background(
188 Background::CreateSolidBackground(SK_ColorWHITE));
189 contents_container_->layer()->SetScrollable(
190 contents_viewport_->layer(), true /* can_overscroll */,
191 base::Bind(&ScrollView::OnLayerScrolled, base::Unretained(this)));
145 } 192 }
146 193
147 ScrollView::~ScrollView() { 194 ScrollView::~ScrollView() {
148 // The scrollbars may not have been added, delete them to ensure they get 195 // The scrollbars may not have been added, delete them to ensure they get
149 // deleted. 196 // deleted.
150 delete horiz_sb_; 197 delete horiz_sb_;
151 delete vert_sb_; 198 delete vert_sb_;
152 delete corner_view_; 199 delete corner_view_;
153 } 200 }
154 201
155 // static 202 // static
156 ScrollView* ScrollView::CreateScrollViewWithBorder() { 203 ScrollView* ScrollView::CreateScrollViewWithBorder() {
157 return new ScrollViewWithBorder(); 204 return new ScrollViewWithBorder();
158 } 205 }
159 206
160 void ScrollView::SetContents(View* a_view) { 207 void ScrollView::SetContents(View* a_view) {
161 SetHeaderOrContents(contents_viewport_, a_view, &contents_); 208 SetHeaderOrContents(contents_container_, a_view, &contents_);
162 } 209 }
163 210
164 void ScrollView::SetHeader(View* header) { 211 void ScrollView::SetHeader(View* header) {
165 SetHeaderOrContents(header_viewport_, header, &header_); 212 SetHeaderOrContents(header_viewport_, header, &header_);
166 } 213 }
167 214
168 gfx::Rect ScrollView::GetVisibleRect() const { 215 gfx::Rect ScrollView::GetVisibleRect() const {
169 if (!contents_) 216 if (!contents_)
170 return gfx::Rect(); 217 return gfx::Rect();
171 return gfx::Rect(-contents_->x(), -contents_->y(), 218 gfx::ScrollOffset offset = CurrentOffset();
172 contents_viewport_->width(), contents_viewport_->height()); 219 return gfx::Rect(offset.x(), offset.y(), contents_viewport_->width(),
220 contents_viewport_->height());
173 } 221 }
174 222
175 void ScrollView::ClipHeightTo(int min_height, int max_height) { 223 void ScrollView::ClipHeightTo(int min_height, int max_height) {
176 min_height_ = min_height; 224 min_height_ = min_height;
177 max_height_ = max_height; 225 max_height_ = max_height;
178 } 226 }
179 227
180 int ScrollView::GetScrollBarWidth() const { 228 int ScrollView::GetScrollBarWidth() const {
181 return vert_sb_ ? vert_sb_->GetLayoutSize() : 0; 229 return vert_sb_ ? vert_sb_->GetLayoutSize() : 0;
182 } 230 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 // viewport_size is the total client space available. 308 // viewport_size is the total client space available.
261 gfx::Size viewport_size = viewport_bounds.size(); 309 gfx::Size viewport_size = viewport_bounds.size();
262 // Assumes a vertical scrollbar since most of the current views are designed 310 // Assumes a vertical scrollbar since most of the current views are designed
263 // for this. 311 // for this.
264 int horiz_sb_height = GetScrollBarHeight(); 312 int horiz_sb_height = GetScrollBarHeight();
265 int vert_sb_width = GetScrollBarWidth(); 313 int vert_sb_width = GetScrollBarWidth();
266 viewport_bounds.set_width(viewport_bounds.width() - vert_sb_width); 314 viewport_bounds.set_width(viewport_bounds.width() - vert_sb_width);
267 // Update the bounds right now so the inner views can fit in it. 315 // Update the bounds right now so the inner views can fit in it.
268 contents_viewport_->SetBoundsRect(viewport_bounds); 316 contents_viewport_->SetBoundsRect(viewport_bounds);
269 317
270 // Give |contents_| a chance to update its bounds if it depends on the 318 // Give |contents_| a chance to update its bounds if it depends on its parent
271 // viewport. 319 // bounds.
272 if (contents_) 320 if (contents_) {
321 // The container bounds may need to be made larger later, but use the
322 // viewport bounds to layout the contents.
323 contents_container_->SetBoundsRect(viewport_bounds);
273 contents_->Layout(); 324 contents_->Layout();
325 }
274 326
275 bool should_layout_contents = false; 327 bool should_layout_contents = false;
276 bool horiz_sb_required = false; 328 bool horiz_sb_required = false;
277 bool vert_sb_required = false; 329 bool vert_sb_required = false;
278 if (contents_) { 330 if (contents_) {
279 gfx::Size content_size = contents_->size(); 331 gfx::Size content_size = contents_->size();
280 ComputeScrollBarsVisibility(viewport_size, 332 ComputeScrollBarsVisibility(viewport_size,
281 content_size, 333 content_size,
282 &horiz_sb_required, 334 &horiz_sb_required,
283 &vert_sb_required); 335 &vert_sb_required);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 viewport_bounds.bottom() - contents_y - height_offset); 371 viewport_bounds.bottom() - contents_y - height_offset);
320 } 372 }
321 if (corner_view_required) { 373 if (corner_view_required) {
322 // Show the resize corner. 374 // Show the resize corner.
323 corner_view_->SetBounds(vert_sb_->bounds().x(), horiz_sb_->bounds().y(), 375 corner_view_->SetBounds(vert_sb_->bounds().x(), horiz_sb_->bounds().y(),
324 vert_sb_width, horiz_sb_height); 376 vert_sb_width, horiz_sb_height);
325 } 377 }
326 378
327 // Update to the real client size with the visible scrollbars. 379 // Update to the real client size with the visible scrollbars.
328 contents_viewport_->SetBoundsRect(viewport_bounds); 380 contents_viewport_->SetBoundsRect(viewport_bounds);
329 if (should_layout_contents && contents_) 381 if (should_layout_contents && contents_) {
382 contents_container_->SetBoundsRect(viewport_bounds);
330 contents_->Layout(); 383 contents_->Layout();
384 }
385
386 // Even when |contents_| needs to scroll, it can still be narrower or wider
387 // the viewport. So ensure the scrolling layer can fill the viewport, so that
388 // events will correctly hit it, and overscroll looks correct.
389 gfx::Size container_size = contents_ ? contents_->size() : gfx::Size();
390 container_size.SetToMax(viewport_bounds.size());
391 contents_container_->SetBoundsRect(gfx::Rect(container_size));
331 392
332 header_viewport_->SetBounds(contents_x, contents_y, 393 header_viewport_->SetBounds(contents_x, contents_y,
333 viewport_bounds.width(), header_height); 394 viewport_bounds.width(), header_height);
334 if (header_) 395 if (header_)
335 header_->Layout(); 396 header_->Layout();
336 397
337 CheckScrollBounds(header_viewport_, header_); 398 CheckScrollBounds(header_viewport_, nullptr, header_);
338 CheckScrollBounds(contents_viewport_, contents_); 399 CheckScrollBounds(contents_viewport_, contents_container_, contents_);
400
339 SchedulePaint(); 401 SchedulePaint();
340 UpdateScrollBarPositions(); 402 UpdateScrollBarPositions();
341 } 403 }
342 404
343 bool ScrollView::OnKeyPressed(const ui::KeyEvent& event) { 405 bool ScrollView::OnKeyPressed(const ui::KeyEvent& event) {
344 bool processed = false; 406 bool processed = false;
345 407
346 // Give vertical scrollbar priority 408 // Give vertical scrollbar priority
347 if (vert_sb_->visible()) 409 if (vert_sb_->visible())
348 processed = vert_sb_->OnKeyPressed(event); 410 processed = vert_sb_->OnKeyPressed(event);
(...skipping 23 matching lines...) Expand all
372 vert_sb_->OnMouseEnteredScrollView(event); 434 vert_sb_->OnMouseEnteredScrollView(event);
373 } 435 }
374 436
375 void ScrollView::OnMouseExited(const ui::MouseEvent& event) { 437 void ScrollView::OnMouseExited(const ui::MouseEvent& event) {
376 if (horiz_sb_) 438 if (horiz_sb_)
377 horiz_sb_->OnMouseExitedScrollView(event); 439 horiz_sb_->OnMouseExitedScrollView(event);
378 if (vert_sb_) 440 if (vert_sb_)
379 vert_sb_->OnMouseExitedScrollView(event); 441 vert_sb_->OnMouseExitedScrollView(event);
380 } 442 }
381 443
444 void ScrollView::OnScrollEvent(ui::ScrollEvent* event) {
445 ui::UIScrollInputManager* compositor_scroller =
446 GetWidget()->GetCompositor()->scroll_input_manager();
447 if (compositor_scroller)
448 compositor_scroller->OnScrollEvent(*event);
449 }
450
382 void ScrollView::OnGestureEvent(ui::GestureEvent* event) { 451 void ScrollView::OnGestureEvent(ui::GestureEvent* event) {
383 // If the event happened on one of the scrollbars, then those events are 452 // If the event happened on one of the scrollbars, then those events are
384 // sent directly to the scrollbars. Otherwise, only scroll events are sent to 453 // sent directly to the scrollbars. Otherwise, only scroll events are sent to
385 // the scrollbars. 454 // the scrollbars.
386 bool scroll_event = event->type() == ui::ET_GESTURE_SCROLL_UPDATE || 455 bool scroll_event = event->type() == ui::ET_GESTURE_SCROLL_UPDATE ||
387 event->type() == ui::ET_GESTURE_SCROLL_BEGIN || 456 event->type() == ui::ET_GESTURE_SCROLL_BEGIN ||
388 event->type() == ui::ET_GESTURE_SCROLL_END || 457 event->type() == ui::ET_GESTURE_SCROLL_END ||
389 event->type() == ui::ET_SCROLL_FLING_START; 458 event->type() == ui::ET_SCROLL_FLING_START;
390 459
391 if (vert_sb_->visible()) { 460 if (vert_sb_->visible()) {
392 if (vert_sb_->bounds().Contains(event->location()) || scroll_event) 461 if (vert_sb_->bounds().Contains(event->location()) || scroll_event)
393 vert_sb_->OnGestureEvent(event); 462 vert_sb_->OnGestureEvent(event);
394 } 463 }
395 if (!event->handled() && horiz_sb_->visible()) { 464 if (!event->handled() && horiz_sb_->visible()) {
396 if (horiz_sb_->bounds().Contains(event->location()) || scroll_event) 465 if (horiz_sb_->bounds().Contains(event->location()) || scroll_event)
397 horiz_sb_->OnGestureEvent(event); 466 horiz_sb_->OnGestureEvent(event);
398 } 467 }
399 } 468 }
400 469
401 const char* ScrollView::GetClassName() const { 470 const char* ScrollView::GetClassName() const {
402 return kViewClassName; 471 return kViewClassName;
403 } 472 }
404 473
474 ScrollView* ScrollView::EnclosingScrollView() {
475 return this;
476 }
477
405 void ScrollView::ScrollToPosition(ScrollBar* source, int position) { 478 void ScrollView::ScrollToPosition(ScrollBar* source, int position) {
406 if (!contents_) 479 if (!contents_)
407 return; 480 return;
408 481
482 gfx::ScrollOffset offset = CurrentOffset();
409 if (source == horiz_sb_ && horiz_sb_->visible()) { 483 if (source == horiz_sb_ && horiz_sb_->visible()) {
410 position = AdjustPosition(contents_->x(), position, contents_->width(), 484 position = AdjustPosition(offset.x(), position, contents_->width(),
411 contents_viewport_->width()); 485 contents_viewport_->width());
412 if (-contents_->x() == position) 486 if (offset.x() == position)
413 return; 487 return;
414 contents_->SetX(-position); 488 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()) { 489 } else if (source == vert_sb_ && vert_sb_->visible()) {
420 position = AdjustPosition(contents_->y(), position, contents_->height(), 490 position = AdjustPosition(offset.y(), position, contents_->height(),
421 contents_viewport_->height()); 491 contents_viewport_->height());
422 if (-contents_->y() == position) 492 if (offset.y() == position)
423 return; 493 return;
424 contents_->SetY(-position); 494 offset.set_y(position);
425 } 495 }
496 ScrollToOffset(offset);
497
498 // TODO(tapted): Remove. Not needed for layered scrolling.
426 contents_->SchedulePaintInRect(contents_->GetVisibleBounds()); 499 contents_->SchedulePaintInRect(contents_->GetVisibleBounds());
427 } 500 }
428 501
429 int ScrollView::GetScrollIncrement(ScrollBar* source, bool is_page, 502 int ScrollView::GetScrollIncrement(ScrollBar* source, bool is_page,
430 bool is_positive) { 503 bool is_positive) {
431 bool is_horizontal = source->IsHorizontal(); 504 bool is_horizontal = source->IsHorizontal();
432 int amount = 0; 505 int amount = 0;
433 if (contents_) { 506 if (contents_) {
434 if (is_page) { 507 if (is_page) {
435 amount = contents_->GetPageScrollIncrement( 508 amount = contents_->GetPageScrollIncrement(
(...skipping 61 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 570 // 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 571 // 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 572 // lower/right corner. This is calculated by taking max_x or max_y
500 // and scaling it back by the size of the viewport. 573 // and scaling it back by the size of the viewport.
501 const int new_x = 574 const int new_x =
502 (vis_rect.x() > x) ? x : std::max(0, max_x - contents_viewport_->width()); 575 (vis_rect.x() > x) ? x : std::max(0, max_x - contents_viewport_->width());
503 const int new_y = 576 const int new_y =
504 (vis_rect.y() > y) ? y : std::max(0, max_y - 577 (vis_rect.y() > y) ? y : std::max(0, max_y -
505 contents_viewport_->height()); 578 contents_viewport_->height());
506 579
507 contents_->SetX(-new_x); 580 ScrollToOffset(gfx::ScrollOffset(new_x, new_y));
508 if (header_) 581
509 header_->SetX(-new_x); 582 // TODO(tapted): Remove. Handled in OnLayerScrolled() with layered scrolling.
510 contents_->SetY(-new_y);
511 UpdateScrollBarPositions(); 583 UpdateScrollBarPositions();
512 } 584 }
513 585
514 void ScrollView::ComputeScrollBarsVisibility(const gfx::Size& vp_size, 586 void ScrollView::ComputeScrollBarsVisibility(const gfx::Size& vp_size,
515 const gfx::Size& content_size, 587 const gfx::Size& content_size,
516 bool* horiz_is_shown, 588 bool* horiz_is_shown,
517 bool* vert_is_shown) const { 589 bool* vert_is_shown) const {
518 // Try to fit both ways first, then try vertical bar only, then horizontal 590 // Try to fit both ways first, then try vertical bar only, then horizontal
519 // bar only, then defaults to both shown. 591 // bar only, then defaults to both shown.
520 if (content_size.width() <= vp_size.width() && 592 if (content_size.width() <= vp_size.width() &&
(...skipping 27 matching lines...) Expand all
548 } else { 620 } else {
549 RemoveChildView(control); 621 RemoveChildView(control);
550 control->SetVisible(false); 622 control->SetVisible(false);
551 } 623 }
552 } 624 }
553 625
554 void ScrollView::UpdateScrollBarPositions() { 626 void ScrollView::UpdateScrollBarPositions() {
555 if (!contents_) 627 if (!contents_)
556 return; 628 return;
557 629
630 const gfx::ScrollOffset offset = CurrentOffset();
558 if (horiz_sb_->visible()) { 631 if (horiz_sb_->visible()) {
559 int vw = contents_viewport_->width(); 632 int vw = contents_viewport_->width();
560 int cw = contents_->width(); 633 int cw = contents_->width();
561 int origin = contents_->x(); 634 horiz_sb_->Update(vw, cw, offset.x());
562 horiz_sb_->Update(vw, cw, -origin);
563 } 635 }
564 if (vert_sb_->visible()) { 636 if (vert_sb_->visible()) {
565 int vh = contents_viewport_->height(); 637 int vh = contents_viewport_->height();
566 int ch = contents_->height(); 638 int ch = contents_->height();
567 int origin = contents_->y(); 639 vert_sb_->Update(vh, ch, offset.y());
568 vert_sb_->Update(vh, ch, -origin);
569 } 640 }
570 } 641 }
571 642
643 gfx::ScrollOffset ScrollView::CurrentOffset() const {
644 return contents_container_->layer()->CurrentScrollOffset();
645 }
646
647 void ScrollView::ScrollToOffset(const gfx::ScrollOffset& offset) {
648 contents_container_->layer()->SetScrollOffset(offset);
649 OnLayerScrolled();
650 }
651
652 void ScrollView::OnLayerScrolled() {
653 if (header_) {
654 header_->SetX(-CurrentOffset().x());
655 header_->SchedulePaintInRect(header_->GetVisibleBounds());
656 }
657 UpdateScrollBarPositions();
658 }
659
572 // VariableRowHeightScrollHelper ---------------------------------------------- 660 // VariableRowHeightScrollHelper ----------------------------------------------
573 661
574 VariableRowHeightScrollHelper::VariableRowHeightScrollHelper( 662 VariableRowHeightScrollHelper::VariableRowHeightScrollHelper(
575 Controller* controller) : controller_(controller) { 663 Controller* controller) : controller_(controller) {
576 } 664 }
577 665
578 VariableRowHeightScrollHelper::~VariableRowHeightScrollHelper() { 666 VariableRowHeightScrollHelper::~VariableRowHeightScrollHelper() {
579 } 667 }
580 668
581 int VariableRowHeightScrollHelper::GetPageScrollIncrement( 669 int VariableRowHeightScrollHelper::GetPageScrollIncrement(
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 724
637 VariableRowHeightScrollHelper::RowInfo 725 VariableRowHeightScrollHelper::RowInfo
638 FixedRowHeightScrollHelper::GetRowInfo(int y) { 726 FixedRowHeightScrollHelper::GetRowInfo(int y) {
639 if (y < top_margin_) 727 if (y < top_margin_)
640 return RowInfo(0, top_margin_); 728 return RowInfo(0, top_margin_);
641 return RowInfo((y - top_margin_) / row_height_ * row_height_ + top_margin_, 729 return RowInfo((y - top_margin_) / row_height_ * row_height_ + top_margin_,
642 row_height_); 730 row_height_);
643 } 731 }
644 732
645 } // namespace views 733 } // 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